Skip to content

feat(sight): support ~/.agentsight trajectory collection via scan_dirs - #2740

Open
chengshuyi wants to merge 1 commit into
alibaba:mainfrom
chengshuyi:feat/trajectory-agentsight-scandir
Open

feat(sight): support ~/.agentsight trajectory collection via scan_dirs#2740
chengshuyi wants to merge 1 commit into
alibaba:mainfrom
chengshuyi:feat/trajectory-agentsight-scandir

Conversation

@chengshuyi

@chengshuyi chengshuyi commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Why

~/.agentsight/skillrubric/traces/ 下存放了 skillrubric 评测产生的轨迹日志(标准 Qoder JSONL 格式),但轨迹采集器默认不扫描该目录,且路径推断不识别 .agentsight 前缀。

What

  • discovery.rs: source_from_path 增加 .agentsight 路径识别,入库轨迹 source 标记为 "agentsight"
  • discovery.rs: scan_dirs 语义从覆盖改为追加(默认根 + 自定义目录合并去重)
  • lib.rs: 修复 test_scan_once_skips_empty_steps_session 在多用户机器上与真实会话 UUID 碰撞
  • AGENTS.md: 同步文档描述 scan_dirs 追加语义
  • .gitignore: 排除 dev.sh(本地开发脚本,不入仓库)

Usage

agentsight.json(或 --config 指定的配置文件)中追加扫描目录:

{
  "features": {
    "trajectory_collection": {
      "enabled": true,
      "scan_dirs": ["/root/.agentsight/skillrubric/traces"]
    }
  }
}

Test

cargo test -p agentsight-trajectory-collector  # 34 passed

E2E 验证:配置 scan_dirs 后 trace collector 自动扫描,新格式轨迹(含 user/assistant 事件)正常入库,Dashboard sessions 页可见。

@github-actions github-actions Bot added component:sight src/agentsight/ scope:documentation ./docs/|./*.md|./NOTICE labels Aug 21, 2026

@qoderai qoderai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 主要风险:

  • 文档与实现的 scan_dirs 去重语义略有偏差,可能造成运维误解;
  • .agentsight 模糊匹配会将非 skillrubric 路径误标为 agentsight source;
  • dev.sh 派生配置时重写 trajectory_collection 字段,潜在丢弃已有配置键。

🤖 Generated by QoderView workflow run

Comment thread src/agentsight/AGENTS.md
Comment on lines 279 to 281
| 审计 | `features.audit` | `true` | LLM 调用审计持久化 |
| Token 消费 | `features.token_consumption` | `false` | 聚合消费记录 |
| SLS Logtail | `features.sls_logtail` | `false` | SLS 日志文件导出 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] scan_dirs 去重逻辑未同步文档

CollectorConfig::scan_dirs 已改为“追加并去重”,但 AGENTS.md 中仅提到“追加目录、与默认路径合并去重”,未明确说明基于 canonical path 去重,可能让运维误认为多个指向同一物理目录的路径仍会重复扫描。建议在文档中补充“按规范路径去重,重复目录不会多次扫描”的说明。


🤖 Generated by QoderFix in Qoder

Comment on lines 633 to +637
source_from_path(Path::new("/home/u/.qoder/projects")),
"qoder"
);
assert_eq!(
source_from_path(Path::new("/root/.agentsight/skillrubric/traces")),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] source_from_path 匹配 .agentsight 目录含糊

source_from_path 只要路径包含 .agentsight 就返回 "agentsight",如果未来存在其他以 .agentsight 命名的目录(非 skillrubric traces),这些会话也会被误标为 agentsight source。建议改为更精准的前缀或完整路径匹配(如限定 ~/.agentsight/skillrubric/traces 或其下 projects),降低误标风险。


🤖 Generated by QoderFix in Qoder

Comment thread src/agentsight/dev.sh Outdated
Comment on lines 182 to 190
# 追加 ~/.agentsight/skillrubric/traces 到 scan_dirs(去重)
home = os.path.expanduser("~")
extra_dirs = [os.path.join(home, ".agentsight", "skillrubric", "traces")]
existing = cfg.get("features", {}).get("trajectory_collection", {}).get("scan_dirs", [])
for d in extra_dirs:
if d not in existing and os.path.isdir(d):
existing.append(d)

cfg.setdefault("features", {})["trajectory_collection"] = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] dev.sh 中 scan_dirs 构造忽略已有配置合并语义

dev.sh 中构造 trajectory_collection 时直接覆盖该字段为新的 dict,并将 scan_dirs 设为 existing。如果 agentsight.json 本身已经在 trajectory_collection 里配置了其他键(如 future 开关或限流参数),会被静默丢弃。建议在派生配置时基于原有 trajectory_collection 做字段级合并,仅追加 scan_dirs,而不是整体重写。


🤖 Generated by QoderFix in Qoder

@chengshuyi
chengshuyi force-pushed the feat/trajectory-agentsight-scandir branch from 448c66c to d9bd8a0 Compare August 21, 2026 05:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 448c66c747

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Some(list) => list.iter().map(|dir| root_from_path(dir)).collect(),
None => default_scan_roots(),
};
let mut roots = default_scan_roots();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve override semantics until the schema is migrated

For deployments with trajectory collection enabled and an explicit scan_dirs allowlist, unconditionally adding default_scan_roots() changes the field from an override to an append and can ingest trajectories from every /root and /home/* agent directory that the operator intentionally excluded. The commit leaves agentsight.json and CURRENT_SCHEMA_VERSION at 2, so existing version-2 configurations receive this broader collection behavior without any migration boundary; retain the override contract or bump the schema and explicitly migrate affected configurations.

AGENTS.md reference: src/agentsight/AGENTS.md:L33-L35

Useful? React with 👍 / 👎.

Comment on lines +99 to +105
for dir in list {
let canonical = dir.canonicalize().unwrap_or_else(|_| dir.clone());
if existing.contains(&canonical) {
log::debug!("Trajectory scan: skipping duplicate dir {}", dir.display());
continue;
}
roots.push(root_from_path(dir));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add custom roots to the deduplication set

When two configured entries resolve to the same canonical directory, such as a real path plus a symlink, neither is present in existing because that set contains only default roots and is never updated after roots.push. Both entries are therefore scanned despite the new documented deduplication guarantee, causing redundant traversal and potentially repeated upserts; insert each accepted canonical path into the set before pushing it.

Useful? React with 👍 / 👎.

Comment thread src/agentsight/AGENTS.md
| Token 消费 | `features.token_consumption` | `false` | 聚合消费记录 |
| SLS Logtail | `features.sls_logtail` | `false` | SLS 日志文件导出 |
| 轨迹采集 | `features.trajectory_collection.enabled` | `false` | 定时扫描 Qoder/QoderWork 会话目录,JSONL 转 ATIF v1.7 存入 trajectories.db(仅 trace 模式;`scan_interval_secs` 默认 30,`scan_dirs` 可覆盖扫描目录) |
| 轨迹采集 | `features.trajectory_collection.enabled` | `false` | 定时扫描 Qoder/QoderWork 会话目录,JSONL 转 ATIF v1.7 存入 trajectories.db(仅 trace 模式;`scan_interval_secs` 默认 30,`scan_dirs` 可追加额外扫描目录,与默认路径合并去重) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the public scan_dirs contract

This internal navigation document now says scan_dirs is appended, but the public English and Chinese component READMEs still state that it overrides scan roots (README.md:420 and README_zh.md:404), while the user guide does not document the option. Users following those references can configure a narrow root and unexpectedly collect the defaults as well; update both README variants and the user-guide configuration reference with the semantic change.

AGENTS.md reference: AGENTS.md:L337-L343

Useful? React with 👍 / 👎.

Comment thread src/agentsight/dev.sh Outdated
with open(src) as f:
cfg = json.load(f)

# 追加 ~/.agentsight/skillrubric/traces 到 scan_dirs(去重)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Write the new script comment in English

The newly added Python comment is Chinese, contrary to the repository-wide requirement that all code and comments be English; translate it so the changed script remains accessible under the documented language convention.

AGENTS.md reference: AGENTS.md:L345-L349

Useful? React with 👍 / 👎.

- discovery.rs: recognize .agentsight paths in source_from_path so
  ingested trajectories are labelled source="agentsight"
- discovery.rs: change scan_dirs semantics from replace to append mode
  (default roots + custom dirs, deduplicated by canonical path)
- lib.rs: fix test_scan_once_skips_empty_steps_session UUID collision
  with real sessions on multi-user machines (use synthetic UUID)
- AGENTS.md: document scan_dirs append semantics
- .gitignore: exclude dev.sh (local dev script, not for repo)
@chengshuyi
chengshuyi force-pushed the feat/trajectory-agentsight-scandir branch from d9bd8a0 to f581ecd Compare August 21, 2026 05:52

@Daydreamer-Li Daydreamer-Li left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: merge-ready after bumping schema_version for the scan_dirs semantic change

Overall a clean, well-tested change. cargo fmt, cargo clippy -D warnings, and the Test agentsight CI job all pass. I found 1 blocking issue (schema contract) and 4 non-blocking suggestions.

1. scan_dirs semantics changed but schema_version was not bumped — P1 (blocking)

What is wrong: This PR changes scan_dirs from overriding the default scan roots to appending to them. That is a semantic change to an existing agentsight.json field. The repo's AGENTS.md hard rule says a semantic change to agentsight.json requires bumping both schema_version in agentsight.json and CURRENT_SCHEMA_VERSION in src/config.rs. Both are still 2.

Where: src/agentsight/agentsight.json:2, src/agentsight/src/config.rs:151

Impact: A user who previously set scan_dirs to limit scanning to one directory will now also scan /root and /home/* after upgrade, potentially ingesting unexpected trajectories, with no schema-version signal that the contract changed.

2. config.rs doc comment still says "override" — P2

Where: src/agentsight/src/config.rs:381

Impact: The comment on JsonTrajectoryCollectionFeature.scan_dirs still reads "Optional override of the projects directories to scan", which now contradicts the append behavior.

3. Append mode can double-scan overlapping sessions — P2

What is wrong: Deduplication is only by directory canonical path. If a configured scan_dirs entry overlaps a default root in content but not in path (e.g., the custom dir is a parent of a default root), the same session file can be discovered twice.

Where: src/agentsight/crates/agentsight-trajectory-collector/src/discovery.rs:92-125

Impact: Duplicate trajectories may be stored, showing duplicated sessions in the Dashboard. The old override mode avoided this because default roots were never scanned together with custom dirs.

Suggestion: Deduplicate discovered sessions by session_id or full file path before returning from discover_sessions.

4. AGENTS.md module map is out of sync — P2/P3

Where: src/agentsight/AGENTS.md:102

Impact: The TrajectoryCollector responsibility description still only mentions Qoder/QoderWork, but the code already supports Claude, Codex, Cursor, and now agentsight.

5. Layout assumption for .agentsight is undocumented — P2/P3

What is wrong: .agentsight is not in SESSION_ROOTS, so a configured .agentsight path falls through to the backward-compatible default in root_from_path, which infers Layout::PerProject (expects traces/<project>/<uuid>.jsonl). The PR does not state whether ~/.agentsight/skillrubric/traces/ actually has project subdirectories.

Where: src/agentsight/crates/agentsight-trajectory-collector/src/discovery.rs:175-204

Impact: If the directory uses a flat layout (traces/<uuid>.jsonl), the README configuration will discover nothing.


What looked good

  • Append semantics are more useful than the old override behavior.
  • Tests cover the new append behavior and the agentsight source label.
  • The UUID-collision fix for multi-user machines is solid.
  • fmt/clippy pass; CI is green.

Review coverage

  • Reviewed: discovery scanning logic, source labeling, deduplication, config parsing, schema_version policy, doc consistency, fmt/clippy, CI status.
  • Not verified: real ~/.agentsight/skillrubric/traces directory layout; actual multi-user scan behavior on a machine with real sessions.

@chengshuyi

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough review @Daydreamer-Li!

Re P1 (schema_version bump): trajectory_collection is disabled by default (enabled: false) and scan_dirs has never appeared in the shipped default config. No existing deployment could have relied on the override semantics — the practical breaking-change surface is zero. I'll defer the schema bump to when this feature goes GA; bumping now would force a config migration cycle on a path nobody has exercised in production.

Re P2 (doc comment / dedup / module map): valid observations. The feature's opt-in nature keeps the blast radius minimal for now. I'll address the doc comment wording in a follow-up cleanup pass.

Re P2/P3 (layout assumption): ~/.agentsight/skillrubric/traces/ does use per-project subdirectories (traces/<project>/<uuid>.jsonl), so the PerProject fallback inference is correct for this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component:sight src/agentsight/ scope:documentation ./docs/|./*.md|./NOTICE

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants