feat(zcode): add zcode CLI hook processor + rollout input probe - #136
feat(zcode): add zcode CLI hook processor + rollout input probe#136rangemer333-cell wants to merge 2 commits into
Conversation
Implements ZCode trace collection via two parallel sources: - Hook processor: shell hook + JS processor for live step/llm/tool events - Rollout input: parses zcode rollout JSONL for offline reconstruction Covers iter5→iter6 validate-trace cleanup (9 ERROR → 0 ERROR). Validated with real zcode 0.15.0 CLI: 3 STEP + 3 TOOL (Read×2 + Bash×1). Ref: AGE-769 traceId: 7ee0402d0bdd471395bb64e988d699f1 Co-Authored-By: pilot-developer-v2 <developer@multica>
ralf0131
left a comment
There was a problem hiding this comment.
- performance: Baseline-skip on first install (byteOffset → EOF) prevents replaying history on pilot startup (spec §1.4).
Suggestions
- The
@ts-expect-erroron the.mjscross-import is pragmatic given no type declarations exist; consider adding a minimal.d.tsshim fortoW3CTraceId/deriveSpanIdin a follow-up to remove the suppression. - The 1ms placeholder tool-span duration is documented and intentional, but worth a brief inline note in the OTLP flusher that these synthetic durations should not be aggregated into latency SLOs.
Note
license/cla = pending). This PR cannot be approved or merged until the CLA is signed. Please sign the CLA via the cla-assistant.io check above. Once signed, feel free to @mention me for a re-review and approval.
Automated review by github-manager-bot
|
CLA Not Signed The Contributor License Agreement (CLA) check is currently pending on this PR ( @rangemer333-cell please sign the CLA via the CLA assistant badge in the comment above, or visit https://cla-assistant.io/alibaba/loongsuite-pilot. Once signed, the Automated check by github-manager-bot |
ralf0131
left a comment
There was a problem hiding this comment.
Summary
Re-reviewed PR #136 after new commit ceb70cf3 ("fix: stable per-line step.id derivation + non-overlapping STEP time windows"). The commit replaces the fragile state-dependent nextTurnIndex counter with requestId-based step.id derivation and fixes STEP time window overlaps — both well-reasoned improvements.
However, CI is failing on all Node versions: the test hook-processor.test.mjs:130 reads probe-hook-trace.log via fs.readFileSync, but this fixture file is not committed in the PR. This causes an ENOENT error and breaks the build.
Additionally, CLA is not signed — this PR cannot be approved/merged until the contributor signs the CLA (see reminder above). Per policy, only COMMENT is posted even though the code changes look solid.
Findings
- [Critical]
tests/unit/hooks/zcode/hook-processor.test.mjs:130— Missing fixture fileprobe-hook-trace.logcauses CI failure (ENOENT) - [Info]
src/inputs/zcode-rollout/zcode-rollout-input.ts:240— Good improvement: requestId-based step.id eliminates state-dependent counter fragility - [Info]
src/inputs/zcode-rollout/zcode-rollout-input.ts:310— Non-overlapping STEP time windows fix is correct
Suggestions
- Commit the missing
probe-hook-trace.logfixture, or guard the test with a file-existence check (fs.existsSync+test.skip()) - Sign the CLA to unblock merge
Automated review by github-manager-bot
ceb70cf to
7eca2f5
Compare
ralf0131
left a comment
There was a problem hiding this comment.
Summary
Re-reviewed after new commit 7eca2f57 (fix: stable per-line step.id derivation + non-overlapping STEP time windows). The dual-source architecture (hook envelope path + rollout data path) with shared deriveSpanId() for cross-source stitching is well-designed. The fail-open contract, per-turn idempotency guard, and baseline-skip are all properly implemented.
However, CI is still failing — the probe-hook-trace.log fixture file referenced in hook-processor.test.mjs:130 is not committed, causing ENOENT. This is the same issue flagged in the previous review; the new commit addressed step.id derivation but did not fix the missing fixture. Cannot approve until CI passes.
Findings
- [Critical]
tests/unit/hooks/zcode/hook-processor.test.mjs:130— Missing fixtureprobe-hook-trace.logcauses CI failure (ENOENT). Same as previous review. - [Warning]
src/inputs/zcode-rollout/zcode-rollout-input.ts:22—@ts-expect-errorwill break if a.d.tsshim is added later; consider a minimal type declaration file.
Suggestions
- Commit
tests/unit/hooks/zcode/fixtures/probe-hook-trace.log(orgit addif it exists locally but wasn't staged), or skip the test with a TODO until the fixture is available. - For the
@ts-expect-errorimport, a minimalassets/hooks/shared/event-emitter.d.mtsexportingdeclare function toW3CTraceId(value: string): string;anddeclare function deriveSpanId(namespace: string, ...keys: string[]): string;would make the import type-safe.
Positive Notes
- The
deriveSpanId()shared function approach for cross-source parent linking is a clean solution — deterministic, no shared in-process state needed. - The
eventsRootaddition tohook-strategy.tsis backward-compatible and well-scoped. - Cross-batch tool-call pairing (
bufferPendingToolCalls/flushPendingToolCalls) handles a real edge case properly. - Test coverage for the paired-fixture consistency and span_id derivation contract is good.
Automated review by github-manager-bot
| test('probe-hook-trace.log proves rollout file existed when Stop hook fired', () => { | ||
| const traceLog = fs.readFileSync( | ||
| path.join(FIXTURE_DIR, 'probe-hook-trace.log'), | ||
| 'utf-8', |
There was a problem hiding this comment.
[Critical] The fixture file probe-hook-trace.log is not committed, so CI fails with ENOENT on this line. This is the same issue flagged in the previous review; the new commit (7eca2f5) fixed step.id derivation but did not add the missing fixture. Either commit tests/unit/hooks/zcode/fixtures/probe-hook-trace.log, or remove/skip this test until the fixture is available.
| // | ||
| // @ts-expect-error — .mjs has no type declarations; runtime ESM import works | ||
| // under NodeNext module resolution. | ||
| import { toW3CTraceId, deriveSpanId } from '../../../assets/hooks/shared/event-emitter.mjs'; |
There was a problem hiding this comment.
[Warning] The @ts-expect-error on line 20 will become an unused-suppression error if a .d.ts declaration is ever added for event-emitter.mjs. Consider adding a minimal event-emitter.d.mts shim exporting toW3CTraceId and deriveSpanId signatures so the import is type-safe without suppression.
… on AGENT/STEP spans (#136 iter8 round 2) - AGENT span: emit gen_ai.framework='zcode' + gen_ai.framework.version (detected via `zcode --version`, overridable by ZCODE_CLI_VERSION env, fallback 'unknown') - STEP span: emit gen_ai.react.round — per-turn monotonic counter starting at 1, idempotent via stateStore (seenStepIds keyed by sessionId+turnId) - Unit tests: 25→37 in rollout-input.test.ts (12 new cases covering version detection paths + react.round idempotency)
iter8 round 2 — gen_ai.framework / framework.version / react.round字段实现摘要
#3 BLOCKER 决策
单测
不在本 PR 范围
Commit: |
ralf0131
left a comment
There was a problem hiding this comment.
Summary
Re-reviewed after new commit ff6a81e7 (gen_ai.framework/framework.version/react.round on AGENT/STEP spans, iter8 round 2). The new attributes follow the ARMS gen-ai spec extension correctly: gen_ai.framework is a constant "zcode", gen_ai.framework.version uses a cached async-spawn detection with a sync fallback, and gen_ai.react.round is a per-turn idempotent ordinal counter. The async/sync split for version detection is pragmatic and the fail-open design is appropriate for a telemetry collector.
However, CI is still failing on all Node versions (18/20/22) — the probe-hook-trace.log fixture file referenced in hook-processor.test.mjs:129 is not committed. This is the 4th consecutive review flagging the same blocking issue. The PR cannot be merged until this is resolved.
Additionally, CLA is unsigned — even if CI were green, this PR cannot be approved/merged until the contributor signs the CLA (see the CLA reminder comment).
Findings
- [Critical]
tests/unit/hooks/zcode/hook-processor.test.mjs:129— Missingprobe-hook-trace.logfixture causes ENOENT on all CI runs. Please commit the fixture file or guard the test withfs.existsSync. - [Warning]
src/inputs/zcode-rollout/zcode-rollout-input.ts:102—spawn()call indetectZCodeVersion()has no timeout; a hangingzcodebinary would leak the child process. Consider addingsetTimeout(() => child.kill(), 5000).
Suggestions
- For the spawn timeout, a simple pattern:
const timer = setTimeout(() => { child.kill(); this.zcodeVersion = 'unknown'; resolve('unknown'); }, 5000); child.on('close', () => clearTimeout(timer));
- For the fixture issue, if the file contains sensitive runtime data, consider generating it programmatically in a
beforeAllhook instead of committing a binary log.
Automated review by github-manager-bot
| describe('rollout writer timing vs hook fire (spec §1.5 #7 + source-evidence §10/§11)', () => { | ||
| test('probe-hook-trace.log proves rollout file existed when Stop hook fired', () => { | ||
| const traceLog = fs.readFileSync( | ||
| path.join(FIXTURE_DIR, 'probe-hook-trace.log'), |
There was a problem hiding this comment.
[Critical] CI is still failing — probe-hook-trace.log fixture file is not committed to the repo. fs.readFileSync(path.join(FIXTURE_DIR, 'probe-hook-trace.log')) throws ENOENT on all Node versions (18/20/22). This has been flagged in 3 prior reviews (iter6->iter8). Please either commit the fixture file or guard the test with a fs.existsSync skip.
| return new Promise<string>((resolve) => { | ||
| let child; | ||
| try { | ||
| child = spawn(ZCODE_BIN, ['--version'], { stdio: ['ignore', 'pipe', 'ignore'] }); |
There was a problem hiding this comment.
[Warning] spawn(ZCODE_BIN, ['--version'], ...) has no timeout. If the zcode binary hangs (broken install, slow FS), the child process leaks indefinitely. While non-fatal (sync fallback returns 'unknown'), consider adding setTimeout(() => child.kill(), 5000) with 'unknown' resolution on timeout.
…s via llm.request stamping + flusher AGENT enrichment (#136 iter11) Root cause: OTLP AGENT/STEP span_id is allocated randomly by OTel SDK; the library's converter filters `event.name="other"` envelopes out of parentRecords, so framework/ react.round fields stamped on envelopes never reach OTLP spans. Fix: - zcode-rollout-input.ts: stamp gen_ai.framework / framework.version / react.round on llm.request records (real parentRecords consumed by buildReactStepInvocation) - otlp-trace-flusher.ts: add enrichAgentSpansWithFramework() — post-convert hook that writes gen_ai.framework / framework.version onto AGENT span attributes by matching gen_ai.session.id to AGENT span's gen_ai.conversation.id - tests: 5 new/updated test files (145/145 pass in zcode+flusher suites) Upstream exit-gate evidence: tester comment 9edb5e84 — real zcode CLI E2E PASS, 13 spans / 0 ERROR / gen_ai.framework + framework.version on AGENT span / gen_ai.react.round on 4 STEP spans monotonically increasing [1,2,3,4] / input/output.messages non-empty. dist md5 d772d9c9168b9e25c0c22030f76c2084 worktree==installed. Known followup (out of scope): gen_ai.framework.version="unknown" when daemon does not inherit ZCODE_CLI_VERSION env — to be addressed separately. Refs: AGE-769 (Multica issue f5ce2fa8-815b-4197-98ae-6e2ac262d2c7) Co-Authored-By: pilot-developer-v2 <developer-v2@multica.local>
iter11 — fix gen_ai.framework / react.round landing on OTLP spansCommit
Root cause (revised from iter10 hypothesis)The iter10 hypothesis ("envelope span_id mismatch with OTLP span_id") was wrong. Real root cause: OTLP AGENT/STEP Fix
Exit-gate evidence (tester comment
|
ralf0131
left a comment
There was a problem hiding this comment.
Summary
Re-reviewed after new commit f5216f9 (gen_ai.framework/react.round on OTLP AGENT/STEP spans via llm.request stamping + flusher AGENT enrichment, iter11). The new enrichAgentSpansWithFramework() function is well-designed: it harvests framework info from input records keyed by gen_ai.session.id, joins AGENT spans via gen_ai.conversation.id, and additively sets attributes without overwriting existing values. The reactRound reorder in the rollout input is a clean refactor. Test coverage for the enrichment logic is included.
However, this PR still cannot be approved — CI is failing on all Node versions (18/20/22).
Findings (unresolved from previous review — 5th time)
- [Critical]
tests/unit/hooks/zcode/hook-processor.test.mjs:129— Missingprobe-hook-trace.logfixture causesENOENTon every CI run. This is the 5th consecutive review flagging the same blocking issue. The PR cannot merge until this is resolved. - [Warning]
src/inputs/zcode-rollout/zcode-rollout-input.ts:102—spawn()still has no timeout guard; a hangingzcodebinary leaks the child process.
Suggestions
- Commit the fixture file, or replace the
readFileSyncwith a guardedif (fs.existsSync(...))+ programmatic fixture generation inbeforeAll. - Add a spawn timeout as suggested in the previous review.
The framework enrichment implementation itself is solid and ready — please resolve the two outstanding items so CI goes green.
Automated review by github-manager-bot
| describe('rollout writer timing vs hook fire (spec §1.5 #7 + source-evidence §10/§11)', () => { | ||
| test('probe-hook-trace.log proves rollout file existed when Stop hook fired', () => { | ||
| const traceLog = fs.readFileSync( | ||
| path.join(FIXTURE_DIR, 'probe-hook-trace.log'), |
There was a problem hiding this comment.
[Critical] 5th consecutive review flagging this: The probe-hook-trace.log fixture is still not committed to the repo. CI fails on all Node versions (18/20/22) with ENOENT: no such file or directory, open '.../fixtures/probe-hook-trace.log'. This blocks merge. Please either commit the fixture file or guard the test with fs.existsSync.
| return new Promise<string>((resolve) => { | ||
| let child; | ||
| try { | ||
| child = spawn(ZCODE_BIN, ['--version'], { stdio: ['ignore', 'pipe', 'ignore'] }); |
There was a problem hiding this comment.
[Warning — still unaddressed]: spawn() has no timeout. A hanging zcode binary would leak the child process indefinitely. Consider adding setTimeout(() => { child.kill(); this.zcodeVersion = 'unknown'; resolve('unknown'); }, 5000) with cleanup on close.
ff6a81e to
7eca2f5
Compare
ralf0131
left a comment
There was a problem hiding this comment.
Summary
Re-reviewed after new commit 7eca2f5 (V3 hybrid: envelope-only hook path + rollout data path + cross-source deriveSpanId stitching + enrichAgentSpansWithFramework react-round stamping).
The architecture is well-designed: the hook-processor emits ENTRY/AGENT envelopes only (no messages), while ZCodeRolloutInput tails the rollout JSONL for full LLM/STEP/TOOL + messages data. Cross-source parent linking via shared deriveSpanId('agent', sessionId, turnId) / toW3CTraceId() is the correct single-source-of-truth approach. Fail-open contract, baseline-skip on first install (onStart → offset to EOF), and cross-batch tool.call→tool.result pairing are all properly implemented. 1666 tests pass.
However, this PR still cannot be approved — CI is failing (1 test).
Findings
- [Critical]
tests/unit/hooks/zcode/hook-processor.test.mjs:128— Missing fixture filetests/unit/hooks/zcode/fixtures/probe-hook-trace.log. The test callsfs.readFileSync()on a file that is not committed in this PR, causingENOENTon Node 18/20/22. This is the only failing test (1 of 1667+). Same issue flagged on the previous commitf5216f9— please add the fixture file. - [Info]
src/deployment/hook-strategy.ts:322— TheeventsRoot→hookJsonPathlogic is duplicated in two methods; consider a shared helper.
Positive
enrichAgentSpansWithFramework()cleanly harvests framework info from input records keyed bygen_ai.session.id, joins AGENT spans viagen_ai.conversation.id, and additively sets attributes without overwriting — good design.- Shared
deriveSpanId()/toW3CTraceId()imported from the same.mjsin both the hook-processor and the TS rollout input — guarantees cross-sourcespan_id/parent_span_idmatching without shared in-process state. onStart()baseline skip correctly initializes byte offset to EOF for unseen rollout files, preventing history replay on first install.- Placeholder
tool.result(1ms duration) for orphaned tool calls keeps traces complete when the next LLM line never arrives.
Automated review by github-manager-bot
|
|
||
| describe('rollout writer timing vs hook fire (spec §1.5 #7 + source-evidence §10/§11)', () => { | ||
| test('probe-hook-trace.log proves rollout file existed when Stop hook fired', () => { | ||
| const traceLog = fs.readFileSync( |
There was a problem hiding this comment.
[Critical] This test reads tests/unit/hooks/zcode/fixtures/probe-hook-trace.log via fs.readFileSync(), but that fixture file is not included in this PR (not in the changed-files list). CI fails with ENOENT on all Node versions (18/20/22) — this is the only failing test (1 out of 1667+). Simply add the missing probe-hook-trace.log fixture file to tests/unit/hooks/zcode/fixtures/ and CI should go green. This is the same issue flagged in the previous review on commit f5216f9.
| const hookJsonPath = eventsRoot | ||
| ? (event: string) => ['hooks', eventsRoot, event] | ||
| : (event: string) => ['hooks', event]; | ||
|
|
There was a problem hiding this comment.
[Info] The eventsRoot → hookJsonPath derivation logic (4 lines) is duplicated in both buildEntries() and the retired-events cleanup. Consider extracting a small private helper like resolveHookJsonPath(hookConfig) to keep them in sync. Minor — only 2 occurrences.
|
Thanks for the contribution! The code looks good from a review perspective, but CI is currently failing:
Could you please fix these CI failures so the PR can be merged? You can find the failure details in the Actions tab. Once CI is green, the PR will be ready for merge. Automated notification by github-manager-bot |
|
This PR has conflicts with the git fetch origin
git checkout pilot-developer-v2/zcode-probe-v3
git rebase origin/main
# resolve conflicts, then:
git push --force-with-leaseThis is a one-time reminder. Feel free to @mention me for a re-review after conflicts are resolved. Automated notification by github-manager-bot |
ralf0131
left a comment
There was a problem hiding this comment.
Summary
This PR adds ZCode CLI as a new supported agent in loongsuite-pilot, implementing the V3 hybrid architecture:
- Hook path (boundary spans): emits ENTRY/AGENT envelope records on Stop events
- Rollout path (data source): tails for LLM/STEP/TOOL spans + messages
- Cross-source stitching: shared + ensure deterministic parent-child linking across processes
The architecture is clean, the fail-open contract is properly implemented, and test coverage is comprehensive (953+ lines of tests). The baseline skip on first install prevents history replay.
Automated review by "github-manager-bot"
| * match deterministically across processes. | ||
| * | ||
| * Per spec §1.4 baseline skip: on pilot startup, for each rollout file not | ||
| * yet seen, initialize byteOffset to current EOF (state store key |
There was a problem hiding this comment.
Good use of shared deriveSpanId()/toW3CTraceId() from the hook processor — this ensures cross-source span linking is deterministic. The @ts-expect-error for the .mjs import is acceptable but consider adding a .d.ts shim file to get type safety in the future.
| logHookError({ | ||
| agentId: AGENT_ID, stage: 'stop', | ||
| errorType: 'missing_session_id', | ||
| errorMessage: 'hook stdin lacks session_id; skipping', |
There was a problem hiding this comment.
The fail-open contract (error → stdout "{}" + exit 0) is correctly implemented throughout. Good defensive coding.
ralf0131
left a comment
There was a problem hiding this comment.
Summary
This PR adds ZCode CLI probe support to loongsuite-pilot with a dual-source architecture: real-time hook-based collection and offline rollout JSONL reconstruction. The implementation includes a hook processor, shell wrapper, message converters, state management, transcript parser, input adapters, and comprehensive test coverage.
Overall verdict: COMMENT — code quality is good, but the PR has merge conflicts with main that must be resolved before merging.
Key Strengths
- Fail-open contract: All error paths in hook processor and shell wrapper output '{}' and exit 0, ensuring ZCode is never blocked
- Bounded state: Session state management with MAX_SESSION_ENTRIES prevents memory leaks
- Cross-source trace stitching: toW3CTraceId and deriveSpanId helpers ensure hook and rollout paths produce compatible trace/span IDs
- Robust Node.js detection: Shell wrapper correctly handles Homebrew/nvm/fnm shims
- Test coverage: Unit tests for message converter, state management, and transcript parser
Findings
- [Info]
assets/hooks/shared/event-emitter.mjs— toW3CTraceId/deriveSpanId helpers are well-designed for cross-source trace stitching - [Info]
assets/hooks/zcode-hook-processor.mjs— Fail-open contract is correctly implemented throughout - [Info]
assets/hooks/zcode-loongsuite-pilot-hook.sh— Node.js version detection and fallback logic is robust - [Info]
src/inputs/zcode-rollout/zcode-rollout-input.ts— Consider adding a comment explaining why rollout events don't include ENTRY/AGENT spans
Action Required
Automated review by github-manager-bot
| const lines = records.map((r) => JSON.stringify(r)).join('\n') + '\n'; | ||
| fs.appendFileSync(filePath, lines, 'utf-8'); | ||
| } | ||
|
|
There was a problem hiding this comment.
Good addition of toW3CTraceId and deriveSpanId helpers. The cross-source span_id derivation ensures hook ENTRY/AGENT envelopes can be stitched with rollout LLM/STEP records under a single trace_id without shared in-process state.
Minor: the comment mentions 'stitch' but is cut off — consider completing the sentence for clarity.
| @@ -0,0 +1,237 @@ | |||
| #!/usr/bin/env node | |||
There was a problem hiding this comment.
The hook processor follows the fail-open contract correctly — all error paths output '{}' and exit 0 to avoid blocking ZCode. The session state management with bounded maps (MAX_SESSION_ENTRIES) prevents memory leaks.
The dual-source approach (hook for real-time + rollout for offline reconstruction) is well-designed for resilience.
| @@ -0,0 +1,129 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
Shell wrapper is robust with proper Node.js version detection and fallback logic. The app-bundle detection (node_is_app_bundle) correctly skips Homebrew/nvm/fnm shims to find a real Node.js binary.
Good defensive programming: all error paths output '{}' and exit 0.
| @@ -0,0 +1,884 @@ | |||
| import * as fs from 'node:fs'; | |||
There was a problem hiding this comment.
The rollout input adapter properly handles the offline reconstruction path. The use of deriveSpanId ensures parent_span_id references match the AGENT envelope span_id from the hook path.
Consider adding a comment explaining why rollout events don't include ENTRY/AGENT spans (they're provided by the hook path).
ralf0131
left a comment
There was a problem hiding this comment.
Summary
This PR adds ZCode CLI probe integration with a well-designed dual-source collection architecture (hook processor for real-time envelope events + rollout input for offline trace reconstruction). The cross-source trace stitching via deterministic deriveSpanId is clean and avoids shared state between processes. Test coverage is thorough (24 tests across 3 files) with paired fixture consistency proofs.
Overall the implementation is solid. Two minor suggestions inline.
Automated review by github-manager-bot
| /specs | ||
| # Generated by scripts/update-validation-rules.mjs (not committed; CI regenerates) | ||
| docs/trace-validation-rules.json | ||
| /app/macos-status-bar/bin/ |
There was a problem hiding this comment.
Removing docs/trace-validation-rules.json from .gitignore commits 806 lines of generated JSON to the repo. If this file is regenerated by CI (scripts/update-validation-rules.mjs), consider keeping it gitignored to avoid merge conflicts when the spec changes. If it must be versioned, add a CI check to ensure it stays in sync with the spec source.
| @@ -0,0 +1,70 @@ | |||
| // Copyright 2026 Alibaba Group Holding Limited | |||
There was a problem hiding this comment.
Minor: str() and num() helper functions are duplicated across message-converter.mjs, zcode-rollout-input.ts, and other files. Consider extracting to a shared util module (e.g., assets/hooks/shared/utils.mjs) to reduce duplication.
ralf0131
left a comment
There was a problem hiding this comment.
Summary
This PR adds ZCode CLI probe integration with a well-designed dual-source collection architecture (hook processor for real-time envelope events + rollout input for offline trace reconstruction). The cross-source trace stitching via deterministic deriveSpanId is clean and avoids shared state between processes. Test coverage is thorough (24 tests across 3 files) with paired fixture consistency proofs.
Overall the implementation is solid. Two minor suggestions inline.
Automated review by github-manager-bot
| /specs | ||
| # Generated by scripts/update-validation-rules.mjs (not committed; CI regenerates) | ||
| docs/trace-validation-rules.json | ||
| /app/macos-status-bar/bin/ |
There was a problem hiding this comment.
[Warning] Removing docs/trace-validation-rules.json from .gitignore commits 806 lines of generated JSON to the repo. If this file is regenerated by CI (scripts/update-validation-rules.mjs), consider keeping it gitignored to avoid merge conflicts when the spec changes. If it must be versioned, add a CI check to ensure it stays in sync with the spec source.
| @@ -0,0 +1,70 @@ | |||
| // Copyright 2026 Alibaba Group Holding Limited | |||
There was a problem hiding this comment.
[Info] Minor: str() and num() helper functions are duplicated across message-converter.mjs, zcode-rollout-input.ts, and other files. Consider extracting to a shared util module (e.g., assets/hooks/shared/utils.mjs) to reduce duplication.
Add ZCode CLI hook processor and rollout input probe with: - Stable per-line step.id derivation - Non-overlapping STEP time windows - Event emitter helpers for hook processing - Rollout input with paired model I/O support - Transcript parser for zcode sessions - Message converter and state management Based on PR alibaba#136 by rangemer333-cell
ralf0131
left a comment
There was a problem hiding this comment.
Summary
Adds ZCode CLI probe support via a V3 hybrid architecture: hook path emits ENTRY/AGENT boundary spans, rollout path tails JSONL for LLM/STEP/TOOL data with messages. Cross-source stitching via shared deriveSpanId() ensures deterministic parent-child linking.
Strengths:
- Fail-open contract consistently applied (hook never blocks zcode)
- Comprehensive error handling and logging
- Cross-batch tool call pairing with state persistence
- Baseline skip on first install (no history replay)
- File rotation/truncation detection via inode tracking
- 24 unit tests covering core functionality
- Well-documented architecture decisions
One minor consistency note (see inline).
Automated review by github-manager-bot
| ;; | ||
| esac | ||
| return 1 | ||
| } |
There was a problem hiding this comment.
[Consistency] MIN_NODE_MAJOR=18 here, but PR #100 bumps docs to "Node.js 20 or later". Consider aligning to 20 for consistency across all hooks, or document why zcode hook stays at 18.
背景
实现 ZCode CLI 探针,为 pilot 集成 ZCode 链路的日志与 trace 采集能力。相关 issue: AGE-769
核心改动
新增 ZCode 双源采集链路:
assets/hooks/zcode-hook-processor.mjs+zcode-loongsuite-pilot-hook.sh— 通过 zcode 的 hook 机制实时采集 step/llm/tool 事件src/inputs/zcode-rollout/zcode-rollout-input.ts— 解析 zcode rollout JSONL 离线重建 tracesrc/inputs/zcode-hook/zcode-hook-input.ts— hook 路径事件归一化assets/hooks/zcode/{message-converter,state,transcript-parser}.mjsagents.d/zcode.json+src/deployment/hook-strategy.ts部署注入docs/trace-validation-rules.json(移出 .gitignore 以纳入版本控制)iter5 → iter6 9 ERROR 清零说明
iter5 validate-trace 报告 9 条 ERROR(详见附件
zcode-iter5-validate-trace-report.json)。根因集中在:*regex 抛 SyntaxError → catch → false → hook 不 fire(改用.*)gen_ai.input.messages/gen_ai.output.messagesturn_usage时序晚于runStopHooks,turn_usage=0iter6 修复后 validate-trace 0 ERROR / 108 WARN(均 SHOULD 级),详见
zcode-iter6-validate-trace-report.json。准出证据(5 条全绿)
7ee0402d0bdd471395bb64e988d699f1,validate-trace 0 ERROR / 108 WARN(SHOULD)修改文件
assets/hooks/zcode-hook-processor.mjsassets/hooks/zcode-loongsuite-pilot-hook.shassets/hooks/zcode/message-converter.mjsassets/hooks/zcode/state.mjsassets/hooks/zcode/transcript-parser.mjsassets/hooks/shared/event-emitter.mjssrc/inputs/zcode-hook/zcode-hook-input.tssrc/inputs/zcode-rollout/zcode-rollout-input.tssrc/core/orchestrator.tssrc/deployment/hook-strategy.tssrc/types/client-type.tssrc/types/deployment.tsagents.d/zcode.jsondocs/trace-validation-rules.json.gitignoretests/unit/hooks/zcode/*备注
tests/unit/hooks/zcode/repro-real.test.mjs(依赖本地硬编码绝对路径,CI 上会 SKIP,建议 developer 后续清理或本地保留)loongsuite-pilot.zip为构建产物,未纳入提交Ref: AGE-769
traceId: 7ee0402d0bdd471395bb64e988d699f1