@hunter-harness/workflow-harness 0.2.19 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
  3. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
  4. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  5. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  6. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
  7. package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
  8. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  9. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
  10. package/harness/bundles/general/claude-code/harness-submit/checklist.md +2 -0
  11. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
  12. package/harness/bundles/general/claude-code/harness-test/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +22 -9
  14. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  15. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  16. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
  17. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  18. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  19. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
  20. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
  21. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  22. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
  23. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +2 -0
  24. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
  25. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +1 -1
  26. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +22 -9
  27. package/harness/bundles/general/codex/.harness-build.json +1 -1
  28. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  29. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
  30. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
  31. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  32. package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
  33. package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
  34. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  35. package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
  36. package/harness/bundles/general/codex/harness-submit/checklist.md +2 -0
  37. package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
  38. package/harness/bundles/general/codex/harness-test/SKILL.md +1 -1
  39. package/harness/bundles/general/codex/scripts/harness_ledger.py +22 -9
  40. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  41. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  42. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
  43. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  44. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  45. package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
  46. package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
  47. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  48. package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
  49. package/harness/bundles/general/cursor/harness-submit/checklist.md +2 -0
  50. package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
  51. package/harness/bundles/general/cursor/harness-test/SKILL.md +1 -1
  52. package/harness/bundles/general/cursor/scripts/harness_ledger.py +22 -9
  53. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  54. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  55. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  56. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
  57. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  58. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  59. package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
  60. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
  61. package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
  62. package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
  63. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
  64. package/harness/bundles/java/claude-code/harness-submit/checklist.md +2 -0
  65. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
  66. package/harness/bundles/java/claude-code/harness-test/SKILL.md +1 -1
  67. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +22 -9
  68. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  69. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  70. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  71. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
  72. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  73. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  74. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
  75. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
  76. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
  77. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
  78. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
  79. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +2 -0
  80. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
  81. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +1 -1
  82. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +22 -9
  83. package/harness/bundles/java/codex/.harness-build.json +1 -1
  84. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  85. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  86. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
  87. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
  88. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  89. package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
  90. package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
  91. package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
  92. package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
  93. package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
  94. package/harness/bundles/java/codex/harness-submit/checklist.md +2 -0
  95. package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
  96. package/harness/bundles/java/codex/harness-test/SKILL.md +1 -1
  97. package/harness/bundles/java/codex/scripts/harness_ledger.py +22 -9
  98. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  99. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  100. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  101. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
  102. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  103. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  104. package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
  105. package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
  106. package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
  107. package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
  108. package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
  109. package/harness/bundles/java/cursor/harness-submit/checklist.md +2 -0
  110. package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
  111. package/harness/bundles/java/cursor/harness-test/SKILL.md +1 -1
  112. package/harness/bundles/java/cursor/scripts/harness_ledger.py +22 -9
  113. package/harness/manifests/general/claude-code.json +13 -13
  114. package/harness/manifests/general/codebuddy.json +13 -13
  115. package/harness/manifests/general/codex.json +13 -13
  116. package/harness/manifests/general/cursor.json +13 -13
  117. package/harness/manifests/java/claude-code.json +15 -15
  118. package/harness/manifests/java/codebuddy.json +15 -15
  119. package/harness/manifests/java/codex.json +15 -15
  120. package/harness/manifests/java/cursor.json +15 -15
  121. package/hunter-workflow-family.json +1 -1
  122. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  name: harness-sync
3
3
  description: 检查并更新项目AI元数据(CodeGraph索引、harness-codebase-map分析、CLAUDE.md、AGENTS.md、.harness/完整性),确保Claude对代码库的理解与最新代码一致。当用户说'同步/更新索引/刷新元数据/检查一致性'时使用
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=20fd2cc48741f11b; overlay=java; agent=codex; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=fa7548f521e44e67; overlay=java; agent=codex; do not edit -->
6
6
  # harness-sync — 元数据同步
7
7
 
8
8
  ## Purpose
@@ -2,7 +2,7 @@
2
2
  name: harness-test
3
3
  description: 测试执行:读取场景表,执行单元测试+API接口测试+数据兼容验证,输出测试报告。当用户说'跑测试/验证/跑用例/接口测试/单元测试'时使用
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=20fd2cc48741f11b; overlay=java; agent=codex; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=fa7548f521e44e67; overlay=java; agent=codex; do not edit -->
6
6
  # harness-test — 测试执行
7
7
 
8
8
  ## Purpose
@@ -28,6 +28,7 @@ if str(SCRIPTS_DIR) not in sys.path:
28
28
  sys.path.insert(0, str(SCRIPTS_DIR))
29
29
 
30
30
  import harness_paths # noqa: E402
31
+ import harness_profile # noqa: E402
31
32
 
32
33
 
33
34
  if hasattr(sys.stdout, "reconfigure"):
@@ -534,18 +535,30 @@ def expand_profile_input_files(
534
535
  ) -> tuple[list[str], str | None]:
535
536
  """Expand verificationInputs[profile_input] globs from build-profile.json.
536
537
 
537
- Globs are relative to project; only files inside project are kept
538
- (deduped, path-sorted). Returns (files, error); error is None on success.
538
+ Profile is loaded via ``harness_profile.load_profile`` (C7: common_root then
539
+ execution overlay) so linked worktrees without a local build-profile still
540
+ reuse the main checkout profile. Globs remain relative to the execution
541
+ ``project`` root (not common_root) so inputsHash tracks the tree under test.
542
+
543
+ Returns (files, error); error is None on success.
539
544
  profile 缺失 / key 缺失 / glob 无匹配 / 结果为空 → 返回 ([], "<reason>"),
540
545
  调用方据此返回 insufficient-evidence,执行全量测试但不允许缓存复用。
541
546
  """
542
- profile_path = project / ".harness" / "config" / "build-profile.json"
543
- if not profile_path.is_file():
547
+ profile = harness_profile.load_profile(Path(project))
548
+ if profile is None:
549
+ # load_profile swallows JSON errors; restore actionable unreadable diag
550
+ # when a profile file exists but cannot be parsed (review YELLOW-1).
551
+ project_root = Path(project).resolve()
552
+ common = harness_paths.common_root(project_root)
553
+ for root in (common, project_root):
554
+ candidate = root / ".harness" / "config" / "build-profile.json"
555
+ if not candidate.is_file():
556
+ continue
557
+ try:
558
+ json.loads(candidate.read_text(encoding="utf-8-sig"))
559
+ except (OSError, json.JSONDecodeError) as exc:
560
+ return [], f"build-profile.json unreadable: {exc}"
544
561
  return [], "build-profile.json missing; run harness_preflight.py detect"
545
- try:
546
- profile = json.loads(profile_path.read_text(encoding="utf-8-sig"))
547
- except (OSError, json.JSONDecodeError) as exc:
548
- return [], f"build-profile.json unreadable: {exc}"
549
562
  if not isinstance(profile, dict):
550
563
  return [], "build-profile.json is not an object"
551
564
  inputs = profile.get("verificationInputs")
@@ -555,7 +568,7 @@ def expand_profile_input_files(
555
568
  if not isinstance(patterns, list) or not patterns:
556
569
  return [], f"verificationInputs.{profile_input} is empty or invalid"
557
570
 
558
- base = project.resolve()
571
+ base = Path(project).resolve()
559
572
  seen: set[str] = set()
560
573
  for pat in patterns:
561
574
  if not isinstance(pat, str) or not pat.strip():
@@ -2,5 +2,5 @@
2
2
  "schemaVersion": 1,
3
3
  "overlay": "java",
4
4
  "agent": "cursor",
5
- "coreHash": "490e7009ad6d80cc"
5
+ "coreHash": "efc5e76ae83a93e6"
6
6
  }
@@ -2,7 +2,7 @@
2
2
  name: harness-apidoc
3
3
  description: 从 Java 后端代码生成结构化前端 API 文档(Controller/VO/ErrorCode)。使用场景:接口文档、前端接口文档、API 文档生成
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
6
6
  # harness-apidoc — 前端接口文档(Java overlay)
7
7
 
8
8
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-archive
3
3
  description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档)到
4
4
  .harness/archive/,含归档元数据和可视化最终总结。使用场景:归档、完成归档、收尾、打包产出物
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
7
7
  # harness-archive — 变更归档
8
8
 
9
9
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-codebase-map
3
3
  description: 分析现有代码库并生成 .harness/codebase/map/
4
4
  下的结构化代码库地图。用于陌生项目理解、重大改造前梳理、harness-sync 提示 map 过期后的人工刷新。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
7
7
  # harness-codebase-map — 代码库地图
8
8
 
9
9
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-knowledge-ingest
3
3
  description: 从 .harness/archive 归档整理、同步和维护项目知识索引。适用场景:ingest knowledge、sync
4
4
  knowledge、rebuild knowledge index、promote knowledge、确认知识条目、检查知识库是否过期。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
7
7
  # harness-knowledge-ingest
8
8
 
9
9
  从 `.harness/archive/**/reports/final/summary-data.json` 抽取项目知识,生成并维护本地 `.harness/knowledge/` 索引。
@@ -3,7 +3,7 @@ name: harness-knowledge-query
3
3
  description: 根据新需求、设计任务、代码修改请求或问题排查,在规划和编码前查询 .harness/knowledge
4
4
  历史上下文。适用场景:query knowledge、查找历史需求、根据归档理解需求、继续之前类似开发、生成需求上下文包。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
7
7
  # harness-knowledge-query
8
8
 
9
9
  并行 change 中查询必须传 `--change <change-id>`;成功后以该 change 的 `meta/knowledge-context.json` 为稳定指针。全局 `context-packs/latest.json` 仅向后兼容,不得用于判断多个 active change 的上下文归属。
@@ -2,7 +2,7 @@
2
2
  name: harness-package
3
3
  description: 增量模块打包:拉取最新→编译验证→mvn package→汇总 jar/war。使用场景:打包、package、发版准备
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
6
6
  # harness-package — 增量模块打包(Java overlay)
7
7
 
8
8
  ## Purpose
@@ -2,7 +2,7 @@
2
2
  name: harness-plan
3
3
  description: 将需求转化为设计文档+实施计划+完整测试场景表,必须在编码前完成。使用场景:需求分析、feature plan、技术方案设计、实现方案规划
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
6
6
  # harness-plan — 需求规划
7
7
 
8
8
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-review
3
3
  description: 6维度代码审查(架构/安全/规范/兼容/测试/性能),对照项目规则(见
4
4
  .harness/context-index.json)和测试场景表,在隔离上下文运行。使用场景:代码审查、提交前检查、合并评审
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
7
7
  # harness-review — 代码审查
8
8
 
9
9
  ## Purpose
@@ -2,7 +2,7 @@
2
2
  name: harness-run
3
3
  description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编译验证),逐变更簇实现计划中的任务。使用场景:开始编码、实现功能、写代码、TDD 编码
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
6
6
  # harness-run — 需求编码
7
7
 
8
8
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-submit
3
3
  description: 最终提交封装:验证→中文 commit→提交/推送;worktree 模式含 --no-ff
4
4
  合并回主分支。使用场景:提交代码、commit、push、合并分支、merge to main、完成开发
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
7
7
  # harness-submit — 最终提交(含 worktree 合并)
8
8
 
9
9
  ## Purpose
@@ -369,6 +369,8 @@ powershell.exe -Command "python harness/scripts/harness_check_gate.py --write"
369
369
 
370
370
  ### 步骤 M5:push
371
371
 
372
+ **硬门槛(eslint × feature worktree)**:integration / 主仓 `pre-push` 跑 `npm run check` 时,eslint 不得把 sibling `.worktrees/<change>/` 当成第二工程根(双 `tsconfigRootDir`)。本仓以 `eslint.config.mjs` 的 `.worktrees/**` ignore 为准;若自定义 eslint 未 ignore,须先 `move_agent_to_root(<projectRoot>)` 再清 feature worktree,再 push。
373
+
372
374
  ```powershell
373
375
  python harness/scripts/harness_integration.py push --change <change-name> --run-id <run-id> --feature-branch harness/<change-name> --target-branch <主分支> --temp-root <task-temp>
374
376
  ```
@@ -2,7 +2,7 @@
2
2
  name: harness-sync
3
3
  description: 检查并更新项目AI元数据(CodeGraph索引、harness-codebase-map分析、CLAUDE.md、AGENTS.md、.harness/完整性),确保Claude对代码库的理解与最新代码一致。当用户说'同步/更新索引/刷新元数据/检查一致性'时使用
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
6
6
  # harness-sync — 元数据同步
7
7
 
8
8
  ## Purpose
@@ -2,7 +2,7 @@
2
2
  name: harness-test
3
3
  description: 测试执行:读取场景表,执行单元测试+API接口测试+数据兼容验证,输出测试报告。当用户说'跑测试/验证/跑用例/接口测试/单元测试'时使用
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=490e7009ad6d80cc; overlay=java; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=efc5e76ae83a93e6; overlay=java; agent=cursor; do not edit -->
6
6
  # harness-test — 测试执行
7
7
 
8
8
  ## Purpose
@@ -28,6 +28,7 @@ if str(SCRIPTS_DIR) not in sys.path:
28
28
  sys.path.insert(0, str(SCRIPTS_DIR))
29
29
 
30
30
  import harness_paths # noqa: E402
31
+ import harness_profile # noqa: E402
31
32
 
32
33
 
33
34
  if hasattr(sys.stdout, "reconfigure"):
@@ -534,18 +535,30 @@ def expand_profile_input_files(
534
535
  ) -> tuple[list[str], str | None]:
535
536
  """Expand verificationInputs[profile_input] globs from build-profile.json.
536
537
 
537
- Globs are relative to project; only files inside project are kept
538
- (deduped, path-sorted). Returns (files, error); error is None on success.
538
+ Profile is loaded via ``harness_profile.load_profile`` (C7: common_root then
539
+ execution overlay) so linked worktrees without a local build-profile still
540
+ reuse the main checkout profile. Globs remain relative to the execution
541
+ ``project`` root (not common_root) so inputsHash tracks the tree under test.
542
+
543
+ Returns (files, error); error is None on success.
539
544
  profile 缺失 / key 缺失 / glob 无匹配 / 结果为空 → 返回 ([], "<reason>"),
540
545
  调用方据此返回 insufficient-evidence,执行全量测试但不允许缓存复用。
541
546
  """
542
- profile_path = project / ".harness" / "config" / "build-profile.json"
543
- if not profile_path.is_file():
547
+ profile = harness_profile.load_profile(Path(project))
548
+ if profile is None:
549
+ # load_profile swallows JSON errors; restore actionable unreadable diag
550
+ # when a profile file exists but cannot be parsed (review YELLOW-1).
551
+ project_root = Path(project).resolve()
552
+ common = harness_paths.common_root(project_root)
553
+ for root in (common, project_root):
554
+ candidate = root / ".harness" / "config" / "build-profile.json"
555
+ if not candidate.is_file():
556
+ continue
557
+ try:
558
+ json.loads(candidate.read_text(encoding="utf-8-sig"))
559
+ except (OSError, json.JSONDecodeError) as exc:
560
+ return [], f"build-profile.json unreadable: {exc}"
544
561
  return [], "build-profile.json missing; run harness_preflight.py detect"
545
- try:
546
- profile = json.loads(profile_path.read_text(encoding="utf-8-sig"))
547
- except (OSError, json.JSONDecodeError) as exc:
548
- return [], f"build-profile.json unreadable: {exc}"
549
562
  if not isinstance(profile, dict):
550
563
  return [], "build-profile.json is not an object"
551
564
  inputs = profile.get("verificationInputs")
@@ -555,7 +568,7 @@ def expand_profile_input_files(
555
568
  if not isinstance(patterns, list) or not patterns:
556
569
  return [], f"verificationInputs.{profile_input} is empty or invalid"
557
570
 
558
- base = project.resolve()
571
+ base = Path(project).resolve()
559
572
  seen: set[str] = set()
560
573
  for pat in patterns:
561
574
  if not isinstance(pat, str) or not pat.strip():
@@ -7,7 +7,7 @@
7
7
  "files": [
8
8
  {
9
9
  "path": ".harness-build.json",
10
- "sha256": "a7fd6e4e51c881e477be82f244cc3ab7ee32936d272b04bb0adc89b7b40d3e81"
10
+ "sha256": "164e3dc420cf0c1297b2107160216e08a03966f12dc24dccb65cfaadf2d8b6de"
11
11
  },
12
12
  {
13
13
  "path": "agents/harness-evaluator.md",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  {
49
49
  "path": "harness-archive/SKILL.md",
50
- "sha256": "de28ac18baac77b3ab0881ead2a5aa2caae5cfccd5405104ec5f7b47331cc8c0"
50
+ "sha256": "de3cdccf65400963dd3a8a5d2eb41a422ed1cef951c43e7896e016a26d471392"
51
51
  },
52
52
  {
53
53
  "path": "harness-archive/templates/render-summary.mjs",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  {
69
69
  "path": "harness-codebase-map/SKILL.md",
70
- "sha256": "81fd2ec9fee4da20d650e6dc48ab4ab741f12245c281d853f7a00936c7eb9e0b"
70
+ "sha256": "c67a91e1f274a29cea77d1da8f602a889fb9085e7a82370e5cf5a6064d195139"
71
71
  },
72
72
  {
73
73
  "path": "harness-codebase-map/templates/ARCHITECTURE.md",
@@ -131,11 +131,11 @@
131
131
  },
132
132
  {
133
133
  "path": "harness-knowledge-ingest/SKILL.md",
134
- "sha256": "ab3a09a404d69852376aaba528abbe44b831aca48f9763783af71fb0efcacf9b"
134
+ "sha256": "3fa651d2ce8962e83f05b518df1a09fafa7e5a01ea9e6038776a753ab241c261"
135
135
  },
136
136
  {
137
137
  "path": "harness-knowledge-query/SKILL.md",
138
- "sha256": "7e9fb5f54f07bf2b2394e14be136fe771835c082e40fe7f61206fc11a22bae4e"
138
+ "sha256": "7dccc07f4fbfd5dc2dee1db50c53d1eb8b4990d106f8a592e64f383e056921f1"
139
139
  },
140
140
  {
141
141
  "path": "harness-plan/checklist.md",
@@ -151,7 +151,7 @@
151
151
  },
152
152
  {
153
153
  "path": "harness-plan/SKILL.md",
154
- "sha256": "34df4f0e7e0fa656800b0546e3a724c86c95c96ebf990f145a93154a88dda70e"
154
+ "sha256": "58ee9c2ab2485b895b2aa971025e5d1c330cf140babbb3857f7bc2ea8331e958"
155
155
  },
156
156
  {
157
157
  "path": "harness-review/checklist.md",
@@ -167,7 +167,7 @@
167
167
  },
168
168
  {
169
169
  "path": "harness-review/SKILL.md",
170
- "sha256": "ce103208e022e238bdd0b6e501c4faf9194b95ed2d736c52816b004eda4812b0"
170
+ "sha256": "8bddef05374f53c1956752c434d70bfa65063136ad111d67f1616ca9ff74e598"
171
171
  },
172
172
  {
173
173
  "path": "harness-run/checklist.md",
@@ -183,11 +183,11 @@
183
183
  },
184
184
  {
185
185
  "path": "harness-run/SKILL.md",
186
- "sha256": "ee22d79c40fbf24d2ab7eba24448c7e89274bb2a81c7d6875fcc526cfd03e771"
186
+ "sha256": "7cf03717705f385cbca018145306c4281ff95324d19294856b2b4d45f7cd3686"
187
187
  },
188
188
  {
189
189
  "path": "harness-submit/checklist.md",
190
- "sha256": "54230792cd9716c663ba3e7f569846910f67d0f0955bf38bafb653062111357c"
190
+ "sha256": "2ebc0bc1ac5ce8cf13760ca967870b318633adaebbe0492a99152497d3285582"
191
191
  },
192
192
  {
193
193
  "path": "harness-submit/reference.md",
@@ -195,7 +195,7 @@
195
195
  },
196
196
  {
197
197
  "path": "harness-submit/SKILL.md",
198
- "sha256": "3d32ae7ee46dbad5fac6f1363f67e16c6fd9ec0cbdddff926a8ce37b95349c82"
198
+ "sha256": "cd1b2470ee449a04b4a6065c1e4108f28840831a6c4293ee3ae634ef488e774a"
199
199
  },
200
200
  {
201
201
  "path": "harness-sync/reference.md",
@@ -203,7 +203,7 @@
203
203
  },
204
204
  {
205
205
  "path": "harness-sync/SKILL.md",
206
- "sha256": "02f0b36925dc6e7da64a5674b15e2395c40c4eb91d17ae169c4d557882156dff"
206
+ "sha256": "5d8b90759a12971b45c424915e4055d812680c23b3596a77dfb86ceb69107500"
207
207
  },
208
208
  {
209
209
  "path": "harness-test/checklist.md",
@@ -227,7 +227,7 @@
227
227
  },
228
228
  {
229
229
  "path": "harness-test/SKILL.md",
230
- "sha256": "f4a9e2b2d3724d3df2bc0a98784c8dd0cd56c99cd726ecba9669e3d10639694e"
230
+ "sha256": "d284a936c3fec8cc427babc880ccdc17110432c8b19933952795f34e948f059c"
231
231
  },
232
232
  {
233
233
  "path": "protocols/archive-report-protocol.md",
@@ -299,7 +299,7 @@
299
299
  },
300
300
  {
301
301
  "path": "scripts/harness_ledger.py",
302
- "sha256": "6d6b5fd9626178d5c10d0fd878f5a31c137b8b292e6a65838f6f06e0991e7576"
302
+ "sha256": "7885b89510a8975c93fe367f9e557735ed70eb6d913f302b6aea3fa193af0f23"
303
303
  },
304
304
  {
305
305
  "path": "scripts/harness_paths.py",
@@ -7,7 +7,7 @@
7
7
  "files": [
8
8
  {
9
9
  "path": ".harness-build.json",
10
- "sha256": "ba0b0fced31b46fda93feb03a5a13da070ebe1fd908533e72653167652b51387"
10
+ "sha256": "21328353c5edb426d87d42d53c2c61e10accdabc06d2aac4f28c5bccfbe37c95"
11
11
  },
12
12
  {
13
13
  "path": "agents/harness-evaluator.md",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  {
49
49
  "path": "harness-archive/SKILL.md",
50
- "sha256": "1a341e5577d13e452cf0c104589c7715b6daa839fbf69a8e1a85d508452f6364"
50
+ "sha256": "1aa6760b6d589c6e11f7f9509de10fcf2d45004f353d909b044477c1e60e60fc"
51
51
  },
52
52
  {
53
53
  "path": "harness-archive/templates/render-summary.mjs",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  {
69
69
  "path": "harness-codebase-map/SKILL.md",
70
- "sha256": "f510002d2e2c049c2b00e46c513adb0f4106bb8b30f9dba8d4a076e513f513c3"
70
+ "sha256": "78388513d79e0b2d9108d97aa9edc07cb388db8af8020577227fd7fb779a6f81"
71
71
  },
72
72
  {
73
73
  "path": "harness-codebase-map/templates/ARCHITECTURE.md",
@@ -131,11 +131,11 @@
131
131
  },
132
132
  {
133
133
  "path": "harness-knowledge-ingest/SKILL.md",
134
- "sha256": "d7fba15d9471c14b9721796e537102c74e8005c80871b919a6ae55e1786802a1"
134
+ "sha256": "05332ae01141a8b8e44ebb06d03da2134e0b20f51988902eeebae051ddb88240"
135
135
  },
136
136
  {
137
137
  "path": "harness-knowledge-query/SKILL.md",
138
- "sha256": "b78584a590e87fdc2457b9468e0768730e0dc6a0dc542532274172658ba19c0b"
138
+ "sha256": "b852730e5299f2fada7bf09da2286f47117e6a0a64c536a6ba655387bc9955ef"
139
139
  },
140
140
  {
141
141
  "path": "harness-plan/checklist.md",
@@ -151,7 +151,7 @@
151
151
  },
152
152
  {
153
153
  "path": "harness-plan/SKILL.md",
154
- "sha256": "5554c4cc48ab2b05bb89a738156f58354d87c2c0cf2397d2fc388912541293e2"
154
+ "sha256": "d42b3311fd19d2f7226e2cd72e4b5d97d53407e60ccba02ccec51e63c855fe60"
155
155
  },
156
156
  {
157
157
  "path": "harness-review/checklist.md",
@@ -167,7 +167,7 @@
167
167
  },
168
168
  {
169
169
  "path": "harness-review/SKILL.md",
170
- "sha256": "eba3f0acc790a926d9cc7067e4fba4049948d2f1ca68c928cdcf4324a271796f"
170
+ "sha256": "a5a6e53df88bf2d00441f74f0e8c0a7c7b6281ee085ebb337f03c42529e11476"
171
171
  },
172
172
  {
173
173
  "path": "harness-run/checklist.md",
@@ -183,11 +183,11 @@
183
183
  },
184
184
  {
185
185
  "path": "harness-run/SKILL.md",
186
- "sha256": "1b2ecf9d1563faa27b0b38aa610655165992bf482d4a2d458b6ba52fb756bf04"
186
+ "sha256": "bd353d21a0ca8b4d0b90eb059f1d9c716cfe2b86ba90a204b1999c4063174eb0"
187
187
  },
188
188
  {
189
189
  "path": "harness-submit/checklist.md",
190
- "sha256": "54230792cd9716c663ba3e7f569846910f67d0f0955bf38bafb653062111357c"
190
+ "sha256": "2ebc0bc1ac5ce8cf13760ca967870b318633adaebbe0492a99152497d3285582"
191
191
  },
192
192
  {
193
193
  "path": "harness-submit/reference.md",
@@ -195,7 +195,7 @@
195
195
  },
196
196
  {
197
197
  "path": "harness-submit/SKILL.md",
198
- "sha256": "017cc1b8d658143e65978806aee18c795b02304c60e01c77a6503ba93869cc07"
198
+ "sha256": "e709b820e4ab0890cd9433a0b773a0f3a8838f84c89c3238e8082b13257e2d66"
199
199
  },
200
200
  {
201
201
  "path": "harness-sync/reference.md",
@@ -203,7 +203,7 @@
203
203
  },
204
204
  {
205
205
  "path": "harness-sync/SKILL.md",
206
- "sha256": "fab6d711894235a0a43c8bda499dda135454ce13f3cf7511183b756091863180"
206
+ "sha256": "a464f31481c4f047df8d626a9f9e0b5cb2c98308a6e7ead4bd38154d3dfd4ff3"
207
207
  },
208
208
  {
209
209
  "path": "harness-test/checklist.md",
@@ -227,7 +227,7 @@
227
227
  },
228
228
  {
229
229
  "path": "harness-test/SKILL.md",
230
- "sha256": "e9ab2bf7fb5f6501700d48e943cf15f7a1fdb7f9fdb994e8cd90d61b13d0fcd2"
230
+ "sha256": "4c411b5587863864f1114acc3288f827773b471e2b8d7dcd8d0992fdd6470b53"
231
231
  },
232
232
  {
233
233
  "path": "protocols/archive-report-protocol.md",
@@ -299,7 +299,7 @@
299
299
  },
300
300
  {
301
301
  "path": "scripts/harness_ledger.py",
302
- "sha256": "6d6b5fd9626178d5c10d0fd878f5a31c137b8b292e6a65838f6f06e0991e7576"
302
+ "sha256": "7885b89510a8975c93fe367f9e557735ed70eb6d913f302b6aea3fa193af0f23"
303
303
  },
304
304
  {
305
305
  "path": "scripts/harness_paths.py",
@@ -7,7 +7,7 @@
7
7
  "files": [
8
8
  {
9
9
  "path": ".harness-build.json",
10
- "sha256": "52cbf5f48f6ff848c919e06bd2a616c67165868c7b3985f1dc6722ecb5866e04"
10
+ "sha256": "8876d2a1bb2149c66463aa98741cb9cf84b557539918eeae1a416eb4afb7486e"
11
11
  },
12
12
  {
13
13
  "path": "CONTEXT.md",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  {
37
37
  "path": "harness-archive/SKILL.md",
38
- "sha256": "ff182c430076732e9437713a5ff315a743ca7fc25c1944aa6d7206bdf7e36158"
38
+ "sha256": "8d1a41c51b3a0d111eb4bcc20d2bd0852f73198c0392b8ad92cd51169f4379fb"
39
39
  },
40
40
  {
41
41
  "path": "harness-archive/templates/render-summary.mjs",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  {
57
57
  "path": "harness-codebase-map/SKILL.md",
58
- "sha256": "0cf5e715893f8f056ee99eb529071be35bd69a454523ac14ef8b1df183499dcf"
58
+ "sha256": "a99a847858abddc8c5004f14e31e065bd63c890b010ae8281d45de982c036f4c"
59
59
  },
60
60
  {
61
61
  "path": "harness-codebase-map/templates/ARCHITECTURE.md",
@@ -119,11 +119,11 @@
119
119
  },
120
120
  {
121
121
  "path": "harness-knowledge-ingest/SKILL.md",
122
- "sha256": "e0f9fb3ec08d74985f2eba19b4bc4c6827251f2bb4d7eb9082b2d677489379ee"
122
+ "sha256": "6ef9540d6d59e3d73e1e53f671e779196c4f92d554cc9dd145d74a58daa52d9f"
123
123
  },
124
124
  {
125
125
  "path": "harness-knowledge-query/SKILL.md",
126
- "sha256": "f3c024d3f41090bea50b44e96524ff57c5fedbb5aeddded11aa07eefbbab3350"
126
+ "sha256": "6f7ffbcf707109996e13e83e408359f0963e689a7424a9520e30b9486b0342f1"
127
127
  },
128
128
  {
129
129
  "path": "harness-plan/checklist.md",
@@ -139,7 +139,7 @@
139
139
  },
140
140
  {
141
141
  "path": "harness-plan/SKILL.md",
142
- "sha256": "19051852756f719ae7ca24af46a2189bc98419d2111b6cfc388fb02d663122a7"
142
+ "sha256": "8c7c1d4f198cd1c8cb02d262ea8af03b07ac64c7a366d491dc856fb8cab5af8b"
143
143
  },
144
144
  {
145
145
  "path": "harness-review/checklist.md",
@@ -155,7 +155,7 @@
155
155
  },
156
156
  {
157
157
  "path": "harness-review/SKILL.md",
158
- "sha256": "8a1bec3db8727f960012f13b0aad234a2b40c63b45047432f701acc27f4e7dcb"
158
+ "sha256": "858809c447993b8d48811eea5efdc339f6519171f3e4574e5a40770bb28c07cd"
159
159
  },
160
160
  {
161
161
  "path": "harness-run/checklist.md",
@@ -171,11 +171,11 @@
171
171
  },
172
172
  {
173
173
  "path": "harness-run/SKILL.md",
174
- "sha256": "30e61e3385e755f5a560fb19af2224f441b3799b6d5fae695ec0cb7c9b837801"
174
+ "sha256": "8b9efd5c35cd346bf5d5e4cbc28b6c50650b989faf82f655866f92ce887acc4e"
175
175
  },
176
176
  {
177
177
  "path": "harness-submit/checklist.md",
178
- "sha256": "54230792cd9716c663ba3e7f569846910f67d0f0955bf38bafb653062111357c"
178
+ "sha256": "2ebc0bc1ac5ce8cf13760ca967870b318633adaebbe0492a99152497d3285582"
179
179
  },
180
180
  {
181
181
  "path": "harness-submit/reference.md",
@@ -183,7 +183,7 @@
183
183
  },
184
184
  {
185
185
  "path": "harness-submit/SKILL.md",
186
- "sha256": "beacfb608371d20a9f7d73fa1897690e0bea45d664c88c18b403dd38d694048c"
186
+ "sha256": "922a781158d51c61601c426cdd3aa6ef27a605c8009c117fb51e370c91d2e6d9"
187
187
  },
188
188
  {
189
189
  "path": "harness-sync/reference.md",
@@ -191,7 +191,7 @@
191
191
  },
192
192
  {
193
193
  "path": "harness-sync/SKILL.md",
194
- "sha256": "0e59973990c04d2568fcf894abf949260df32497dbb1ef86f0638472ac5f248e"
194
+ "sha256": "e32998cc8a31453c5fd0fdb83e651bce19b136fc0fc0a0208ec541cb01d26a56"
195
195
  },
196
196
  {
197
197
  "path": "harness-test/checklist.md",
@@ -215,7 +215,7 @@
215
215
  },
216
216
  {
217
217
  "path": "harness-test/SKILL.md",
218
- "sha256": "4467b660c0b8aecc79fe2f5044913b6e612a9acb5bbd6e02030719cdd8e87ef3"
218
+ "sha256": "0d37df4d1c1937b28a670e71c75e3ef91e6247108a7bc0c6076299e3e56bf9ff"
219
219
  },
220
220
  {
221
221
  "path": "protocols/archive-report-protocol.md",
@@ -287,7 +287,7 @@
287
287
  },
288
288
  {
289
289
  "path": "scripts/harness_ledger.py",
290
- "sha256": "6d6b5fd9626178d5c10d0fd878f5a31c137b8b292e6a65838f6f06e0991e7576"
290
+ "sha256": "7885b89510a8975c93fe367f9e557735ed70eb6d913f302b6aea3fa193af0f23"
291
291
  },
292
292
  {
293
293
  "path": "scripts/harness_paths.py",