Repository navigation
Preserve compact log event timestamps and report untimed evidence - #74785
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
β PR Code Quality Reviewer completed the code quality review.
|
|
β Test Quality Sentinel completed test quality analysis. Test Quality SentinelOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
π§ Matt Pocock Skills Reviewer has completed the skills-based review. β
|
|
β Ponytail Reviewer completed successfully! Ponytail ReviewerOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
β Design Decision Gate ποΈ completed the design decision gate check. See the comment below for the result and any generated ADR draft. Design Decision Gate ποΈOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
Comment MemoryPeek at saved memory (pr-code-quality-reviewer)Note This comment is managed by comment memory.Expand the saved memory block to view or edit the persistent context for this thread.
|
There was a problem hiding this comment.
Review found one correctness issue in event-time handling: an invalid normalized clock can fall back to a different native numeric timestamp and misrepresent timeUnixNano. Please see the inline comment; otherwise the timestamp projection, privacy handling, and coverage look consistent with the stated design.
π Code quality review by PR Code Quality Reviewer Β· copilot Β· gpt50 Β· ~3 AIC Β· β ~1 AIC Β· β 1.6K
Comment /review to run again
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Regarding the review status update: no code change is needed for the notification itself. The resulting invalid-clock finding was accepted and fixed in 0d3975a. |
|
Regarding the test analysis result: acknowledged as informational, not proof of validation or publication. No specific change was requested; the clock regression and final repository validation passed independently before pushing 0d3975a. |
|
Regarding the skills review status: no change is needed because the notification contains no actionable finding. |
|
Regarding the Ponytail review status: no change is needed because this start notification does not request a code change. |
|
Regarding the design gate result: no design change is requested by the reported_no_action outcome. This status is informational and is not being treated as proof of full completion. |
|
Regarding the managed review memory: the recorded invalid-clock finding was accepted and fixed in 0d3975a. No additional change or edit to managed memory is needed because this comment adds no independent request. |
There was a problem hiding this comment.
π‘ Changes recommended
Retained numeric timestamp provenance bypasses redaction, allowing masked source times to be recovered from exported data.
3 open issues
What changed in this PR
This PR adds source event timestamps to compact unified-session OTLP logs, separating event time from export observation time and exposing timestamp coverage.
Changes:
- Retains normalized numeric clocks and exports source timestamps with nanosecond precision.
- Counts untimed records after transport-budget admission.
- Adds timestamp, masking, and budget tests, plus guidance for interpreting export-quality attributes.
| File | Description |
|---|---|
docs/βsrc/βcontent/βdocs/βspecs/βunified-agent-session-specification.md |
Defines clock preservation and untimed-record requirements. |
docs/βsrc/βcontent/βdocs/βreference/βcompiler-enterprise-environment-controls.md |
Documents timestamps, quality attributes, and query limitations. |
actions/βsetup/βjs/βsend_otlp_session_logs.test.cjs |
Adds timestamp, masking, budget, and delivery coverage. |
actions/βsetup/βjs/βsend_otlp_session_logs.cjs |
Exports event times and counts admitted untimed records. |
actions/βsetup/βjs/βcompact_unified_session.test.cjs |
Tests finite normalized-clock projection. |
actions/βsetup/βjs/βcompact_unified_session.cjs |
Allows finite provenance.timestampMs in compact events. |
Review effort: Balanced (auto)
| const projected = { type: event.type, data, ...projectScalars(event, ["timestamp"]) }; | ||
| if (isRecord(event.provenance)) { | ||
| const provenance = projectScalars(event.provenance, ["component", "phase", "path", "index"]); | ||
| if (typeof event.provenance.timestampMs === "number" && Number.isFinite(event.provenance.timestampMs)) provenance.timestampMs = event.provenance.timestampMs; |
There was a problem hiding this comment.
Fixed in f21e905: session serialization now removes derived provenance.timestampMs whenever its source timestamp is redacted by publication or exporter masks. Regression coverage verifies both masking paths.
| * @returns {string | undefined} | ||
| */ | ||
| function eventTimeUnixNano(event) { | ||
| const isoTime = typeof event.timestamp === "string" ? sessionTimestampNs(event) : undefined; |
There was a problem hiding this comment.
Fixed in f21e905: the shared timestamp parser validates calendar and time components before parsing, and invalid timestamp strings no longer fall back to normalized provenance. Added an impossible-date regression.
| function eventTimeUnixNano(event) { | ||
| const isoTime = typeof event.timestamp === "string" ? sessionTimestampNs(event) : undefined; | ||
| const normalizedTime = typeof event.provenance?.timestampMs === "number" ? sessionTimestampNs({ timestamp: event.provenance.timestampMs }) : undefined; | ||
| const time = isoTime ?? normalizedTime ?? sessionTimestampNs(event); |
There was a problem hiding this comment.
Fixed in f21e905: a supplied but invalid normalized clock stays untimed, and native numeric fallback is now limited to events without provenance. Regression coverage includes out-of-range normalized values.
There was a problem hiding this comment.
Skills-Based Review π§
Applied /diagnosing-bugs and /tdd to the timestamp export path. Requesting changes: one spec-violating fallback and one precision loss, plus a test that misses both.
π Key Themes & Highlights
Key Themes
- Fallback reinterprets out-of-range clocks:
eventTimeUnixNanofalls through to the nativetimestampwhenprovenance.timestampMsis finite but out of range. This breaks the spec rule (spec line 627) that out-of-range times MUST stay unset. - Nanosecond precision loss: OTel
timestampvalues are converted to a doubletimestampMs, so1792522800123456789exports as...787. - Weak test coverage: the out-of-range test at
send_otlp_session_logs.test.cjsline 91 uses-1and8640000000000000, which the uint64 range check already rejects. It never reaches the buggy path. - Calendar validation gap (outside this diff):
sessionTimestampNsinunified_session_order.cjsaccepts impossible dates.2026-02-30T00:00:00Zrolls over to March 2 becauseDate.parsenormalizes it. Validate the calendar date before parsing. Not covered by an inline comment because the file is not in the diff.
Positive Highlights
- β
Keeping
observedTimeUnixNanoseparate fromtimeUnixNanois the right design. - β
The
gh-aw.session.untimed_eventsattribute makes missing clocks visible. - β The new tests cover ISO fractions, timezone offsets, and the uint64 bounds.
Verification
I probed the current code and the suggested fix in Node. The fix matched 15 inputs with 0 mismatches. I did not run the vitest suite, because vitest is not installed in this checkout.
@copilot please address the review comments above.
π§ Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer Β· copilot Β· routed: haiku55 xhigh Β· ~9 AIC Β· β ~1 AIC Β· β 5.4K
Comment /matt to run again
| */ | ||
| function eventTimeUnixNano(event) { | ||
| const isoTime = typeof event.timestamp === "string" ? sessionTimestampNs(event) : undefined; | ||
| const normalizedTime = typeof event.provenance?.timestampMs === "number" ? sessionTimestampNs({ timestamp: event.provenance.timestampMs }) : undefined; |
There was a problem hiding this comment.
[/diagnosing-bugs] OTel nanosecond clocks lose precision here. unified_session.cjs converts the ns string to a double timestampMs (for example 1792522800123.4568), and this line then rebuilds ns from that double. 1792522800123456789 exports as 1792522800123456787. The body keeps the exact value, but timeUnixNano is wrong. The exactNs line in the suggestion on line 38 fixes this by parsing the original digit string.
@copilot please address this.
There was a problem hiding this comment.
Fixed in f21e905: digit-string source clocks are parsed as nanoseconds when normalized provenance is present, preserving all digits. Added a sub-millisecond precision regression.
| } | ||
| ); | ||
|
|
||
| it.each([-1, 8640000000000000])("does not reinterpret an out-of-range normalized clock %j in native timestamp units", async timestampMs => { |
There was a problem hiding this comment.
[/tdd] This test never reaches the fallback. -1 and 8640000000000000 are rejected by the >= 0n and uint64 range checks, so the test passes even with the bug in the comment on line 38. Add the values that expose it, plus a nanosecond digit-string case with sub-millisecond digits so the precision fix stays covered.
π‘ Suggested test cases
it.each([-1, 8640000000000000, 8640000000000001, 1e300])("does not reinterpret an out-of-range normalized clock %j in native timestamp units", async timestampMs => {Also add a case with timestamp: "1792522800123456789" and provenance: { timestampMs: 1792522800123.4568 }, expecting timeUnixNano: "1792522800123456789". The existing sub-millisecond case uses an ISO string, so it skips the precision path.
@copilot please address this.
There was a problem hiding this comment.
Updated in f21e905: the out-of-range cases now include 8640000000000001 and 1e300, and a digit-string nanosecond case verifies exact precision.
| function eventTimeUnixNano(event) { | ||
| const isoTime = typeof event.timestamp === "string" ? sessionTimestampNs(event) : undefined; | ||
| const normalizedTime = typeof event.provenance?.timestampMs === "number" ? sessionTimestampNs({ timestamp: event.provenance.timestampMs }) : undefined; | ||
| const time = isoTime ?? normalizedTime ?? sessionTimestampNs(event); |
There was a problem hiding this comment.
[/diagnosing-bugs] An out-of-range normalized clock falls through to the native timestamp, so the event gets a wrong time instead of none. Example: {timestamp: 1700000000, provenance: {timestampMs: 1e300}} exports 1700000000000000 ns. The spec at line 627 says out-of-range times MUST stay unset, so this violates it. The same path reads an out-of-range seconds clock from audit.jsonl (timestamp: 1e13) as milliseconds, giving year 2286.
π‘ Suggested fix
Only fall back to the native clock when provenance is absent, and parse digit strings with the nanosecond unit:
const exactNs = typeof event.provenance?.timestampMs === "number" && typeof event.timestamp === "string" ? sessionTimestampNs(event, "nanoseconds") : undefined;
const time = isoTime ?? exactNs ?? (event.provenance === undefined ? sessionTimestampNs(event) : normalizedTime);I checked this against 15 probe inputs, including the existing fixtures, with 0 mismatches.
@copilot please address this.
There was a problem hiding this comment.
Fixed in f21e905: invalid normalized clocks cannot fall back to native timestamps, and events with provenance but no valid normalized clock remain untimed. Added coverage for an invalid seconds-based audit.jsonl clock.
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74796 PR FinisherSubmitted for publication (not confirmed pushed): merge of Validation: Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74803 PR finisherSubmitted for publication (not yet confirmed pushed): merge of Validation: vitest could not run (npm registry certificate error blocked install); only a Node sanity check and prettier were run. Review thread replies/resolutions are deferred until the fix is published. PR finisher dispatch requested for the following outstanding work: see review threads 4464792186, 4464792234, 4464792263, 4464828987, 4464828994, 4464829000. Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74812 PR FinisherSubmitted for publication (staged, not confirmed pushed): merge of Validation: Review thread replies/resolutions are deferred until the fix is published. Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74819 PR finisherSubmitted for publication (not confirmed pushed): merged Validation: syntax checks and a manual calendar check only. Vitest could not be installed (npm registry certificate error), so the test suite and Hand-off: review replies/resolutions are deferred until the push is published. A maintainer needs to run CI. Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74828 PR finisherSubmitted for publication (not yet confirmed pushed): merged Validation: only Remaining: review replies and resolutions are deferred until the fix is published. A maintainer needs to re-trigger CI and run the JS tests and Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74840 PR finisherSubmitted for publication (staged, not confirmed): merged Validation: prettier and a manual node check only. Vitest could not be installed because the npm registry certificate was rejected, so the test suite and PR finisher dispatch requested for the following outstanding work: see Sous-chef lines below. Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74847 PR finisherSubmitted for publication (staged, not confirmed): merged Validation: node smoke checks and prettier passed. Vitest could not run locally (npm registry cert failure), so tests are unrun. Review threads are left open pending publication; CI needs a maintainer re-trigger. PR finisher dispatch requested for the following outstanding work: items 1-7 (merge main, review threads on clock masking, calendar validation, OTLP fallback/precision/tests). Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74856 PR FinisherSubmitted for publication (staged, not confirmed pushed): merged Validation: node sanity checks only. vitest could not be installed (npm cert error), and Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74862 PR finisherSubmitted for publication (staged, not confirmed): merged Validation: only a quick Node sanity check of the clock logic. Sous-chef head: 0d3975a Sous-chef work: 36f680bdfa6524de218f6ba2ac6c2d0ea6f53cf52a580afd5128307187a99ceb 61110139dc3bcc66567cc612b195b778b7a5df2a56b0d482f768d7558cae073f 622cc74f57102a9b425a0b36e418a26c49e702fcbcb413edc7fe4c0b70538f61 88845676b8b6d7a90d19cdcc2944e9ce4a8b709b10f9b7bab12909b47cc8c0f5 abb5b8846da5863d6830acc23e9cf9633b7a9736e10ca1f5162d1b87502153c0 f07fe74be3dcb876d553e708591351855dbe50cb944beaf00171cfe4e46e4be5 Sous-chef state: 8f8c60fa4395f9008f881beda7a8e95cf576dd228b896e948d302f3424affea8
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74867 PR finisherSubmitted for publication (not confirmed pushed): merged Validation: could not run vitest/ Review thread replies/resolutions are deferred until the fix is published. Sous-chef head: 0d3975a
|
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74873 PR FinisherSubmitted for publication (staged, not confirmed pushed): merged
Validation: Prettier and Review thread replies/resolutions are deferred until the fix is published. CI needs a maintainer re-trigger after publication. PR finisher dispatch requested for the following outstanding work (items 1β7 above). Sous-chef head: 0d3975a
|
|
@copilot run pr-finisher skill |
|
Note The pull request was not created β a fallback review issue was created instead due to protected file changes: #74879 PR finisher summary (submitted for publication, not confirmed pushed):
Validation: vitest could not be installed (npm registry self-signed cert), so the test suite and Sous-chef head: 0d3975a
|
|
@copilot run pr-finisher skill |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
π This pull request is included in a new release. Release: |


Compact session logs previously exposed only export observation time, limiting event-time analysis and obscuring timestamp coverage. This change exports valid source clocks as standard OTLP
timeUnixNanowhile keepingobservedTimeUnixNanoindependent.Changes
provenance.timestampMsin the compact allowlist for numeric clocks.gh-aw.session.untimed_eventsafter transport-budget admission, preserving privacy masks, trace/span correlation, and existing loss accounting.Validation
npm --prefix actions/setup/js run test:js -- --no-file-parallelism send_otlp_session_logs.test.cjs compact_unified_session.test.cjs otlp_protobuf.test.cjs unified_session_order.test.cjs- 186 tests passed, including local JSON/protobuf delivery, uint64 boundaries, source-clock precision, masking, and mixed timed/untimed budget admission.make fmt-cjs && make lint-cjsnpm --prefix actions/setup/js run typecheckmake agent-report-progress- build, lint, and 108 impacted JavaScript tests passed.No raw-session expansion, provider query pack, deployment, or workflow dispatch.