ultimate-pi 0.20.0 → 0.22.1

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 (149) hide show
  1. package/.agents/skills/harness-context/SKILL.md +3 -3
  2. package/.agents/skills/harness-debate-plan/SKILL.md +2 -2
  3. package/.agents/skills/harness-decisions/SKILL.md +68 -2
  4. package/.agents/skills/harness-eval/SKILL.md +1 -1
  5. package/.agents/skills/harness-git-commit/SKILL.md +72 -0
  6. package/.agents/skills/harness-governor/SKILL.md +6 -6
  7. package/.agents/skills/harness-ls-lint-setup/SKILL.md +59 -0
  8. package/.agents/skills/harness-orchestration/SKILL.md +4 -4
  9. package/.agents/skills/harness-plan/SKILL.md +14 -12
  10. package/.agents/skills/harness-review/SKILL.md +3 -3
  11. package/.agents/skills/harness-sentrux-repair/SKILL.md +48 -0
  12. package/.agents/skills/harness-sentrux-setup/SKILL.md +2 -2
  13. package/.agents/skills/harness-spec/SKILL.md +1 -1
  14. package/.agents/skills/harness-steer/SKILL.md +2 -2
  15. package/.agents/skills/posthog-analyst/SKILL.md +1 -1
  16. package/.agents/skills/sentrux/SKILL.md +6 -4
  17. package/.agents/skills/web-retrieval/SKILL.md +1 -1
  18. package/.agents/skills/wiki-save/SKILL.md +1 -1
  19. package/.pi/PACKAGING.md +6 -0
  20. package/.pi/SYSTEM.md +21 -3
  21. package/.pi/agents/harness/ls-lint-steward.md +49 -0
  22. package/.pi/agents/harness/planning/decompose.md +5 -5
  23. package/.pi/agents/harness/planning/execution-plan-author.md +1 -1
  24. package/.pi/agents/harness/planning/hypothesis-validator.md +1 -1
  25. package/.pi/agents/harness/planning/hypothesis.md +1 -1
  26. package/.pi/agents/harness/planning/plan-adversary.md +1 -1
  27. package/.pi/agents/harness/planning/plan-evaluator.md +2 -2
  28. package/.pi/agents/harness/planning/plan-synthesizer.md +2 -2
  29. package/.pi/agents/harness/planning/review-integrator.md +1 -1
  30. package/.pi/agents/harness/planning/sprint-contract-auditor.md +5 -5
  31. package/.pi/agents/harness/reviewing/evaluator.md +1 -1
  32. package/.pi/agents/harness/running/executor.md +2 -2
  33. package/.pi/agents/harness/sentrux-repair-advisor.md +50 -0
  34. package/.pi/agents/harness/sentrux-steward.md +2 -2
  35. package/.pi/agents/pi-pi/prompt-expert.md +17 -2
  36. package/.pi/auto-commit.json +9 -2
  37. package/.pi/extensions/debate-orchestrator.ts +3 -0
  38. package/.pi/extensions/harness-anchored-edit.ts +7 -9
  39. package/.pi/extensions/harness-ask-user.ts +13 -34
  40. package/.pi/extensions/harness-debate-tools.ts +43 -4
  41. package/.pi/extensions/harness-live-widget.ts +28 -19
  42. package/.pi/extensions/harness-run-context.ts +278 -115
  43. package/.pi/extensions/harness-web-tools.ts +598 -471
  44. package/.pi/extensions/ls-lint-rules-sync.ts +103 -0
  45. package/.pi/extensions/observation-bus.ts +4 -0
  46. package/.pi/extensions/policy-gate.ts +270 -229
  47. package/.pi/extensions/sentrux-rules-sync.ts +2 -0
  48. package/.pi/extensions/soundboard.ts +48 -48
  49. package/.pi/harness/README.md +4 -0
  50. package/.pi/harness/agents.manifest.json +24 -16
  51. package/.pi/harness/agents.policy.yaml +49 -82
  52. package/.pi/harness/docs/adrs/0052-ls-lint-naming-lifecycle.md +45 -0
  53. package/.pi/harness/docs/adrs/0052-sentrux-structured-repair.md +38 -0
  54. package/.pi/harness/docs/adrs/0053-plan-task-clarification-gate.md +39 -0
  55. package/.pi/harness/docs/adrs/0054-harness-native-ask-user.md +40 -0
  56. package/.pi/harness/docs/adrs/0055-auto-commit-coauthor-lifecycle.md +40 -0
  57. package/.pi/harness/docs/adrs/README.md +5 -0
  58. package/.pi/harness/docs/practice-map.md +10 -5
  59. package/.pi/harness/evals/smoke/ls-lint-stub.json +10 -0
  60. package/.pi/harness/evolution/self-healing-rules.json +16 -0
  61. package/.pi/harness/ls-lint/naming.manifest.json +128 -0
  62. package/.pi/harness/sentrux/architecture.manifest.json +1 -1
  63. package/.pi/harness/specs/auto-commit.schema.json +63 -0
  64. package/.pi/harness/specs/ls-lint-manifest-proposal.schema.json +80 -0
  65. package/.pi/harness/specs/ls-lint-signal.schema.json +47 -0
  66. package/.pi/harness/specs/naming-manifest.schema.json +54 -0
  67. package/.pi/harness/specs/plan-task-clarification.schema.json +88 -0
  68. package/.pi/harness/specs/sentrux-diagnostics.schema.json +173 -0
  69. package/.pi/harness/specs/sentrux-repair-plan.schema.json +133 -0
  70. package/.pi/harness/specs/sentrux-report.schema.json +119 -0
  71. package/.pi/harness/specs/sentrux-signal.schema.json +34 -1
  72. package/.pi/lib/agents-policy.d.mts +26 -51
  73. package/.pi/lib/agents-policy.mjs +41 -28
  74. package/.pi/lib/agt/build-evaluation-context.ts +136 -64
  75. package/.pi/lib/ask-user/constants.mjs +3 -0
  76. package/.pi/lib/ask-user/constants.ts +4 -0
  77. package/.pi/lib/ask-user/contracts/glimpse-parse.ts +56 -0
  78. package/.pi/lib/ask-user/contracts/glimpse-payload-build.ts +58 -0
  79. package/.pi/lib/ask-user/contracts/glimpse-payload.ts +38 -0
  80. package/.pi/lib/ask-user/core/questionnaire.ts +74 -0
  81. package/.pi/lib/ask-user/dialog.ts +2 -314
  82. package/.pi/lib/ask-user/fallback.ts +2 -78
  83. package/.pi/lib/ask-user/format.ts +85 -0
  84. package/.pi/lib/ask-user/glimpseui.d.ts +10 -0
  85. package/.pi/lib/ask-user/index.ts +114 -0
  86. package/.pi/lib/ask-user/merge-task-clarification.ts +98 -0
  87. package/.pi/lib/ask-user/policy.mjs +43 -0
  88. package/.pi/lib/ask-user/policy.ts +104 -0
  89. package/.pi/lib/ask-user/presenters/glimpse.ts +130 -0
  90. package/.pi/lib/ask-user/presenters/headless.ts +131 -0
  91. package/.pi/lib/ask-user/presenters/select.ts +60 -0
  92. package/.pi/lib/ask-user/presenters/tui.ts +373 -0
  93. package/.pi/lib/ask-user/presenters/types.ts +13 -0
  94. package/.pi/lib/ask-user/render.ts +40 -9
  95. package/.pi/lib/ask-user/schema.ts +66 -13
  96. package/.pi/lib/ask-user/types.ts +60 -3
  97. package/.pi/lib/ask-user/validate-core.mjs +193 -7
  98. package/.pi/lib/ask-user/validate.ts +53 -34
  99. package/.pi/lib/harness-anchored-edit/package.json +3 -0
  100. package/.pi/lib/harness-artifact-gate.ts +75 -21
  101. package/.pi/lib/harness-auto-commit-config.mjs +321 -0
  102. package/.pi/lib/harness-lens/clients/lsp/client.ts +62 -39
  103. package/.pi/lib/harness-lens/clients/tool-policy.ts +73 -181
  104. package/.pi/lib/harness-lens/index.ts +241 -108
  105. package/.pi/lib/harness-lens/tools/lsp-navigation.ts +10 -8
  106. package/.pi/lib/harness-repair-brief.ts +84 -25
  107. package/.pi/lib/harness-run-context.ts +42 -52
  108. package/.pi/lib/harness-sentrux-parse.mjs +272 -0
  109. package/.pi/lib/harness-sentrux-root.mjs +78 -0
  110. package/.pi/lib/harness-slash-completions.ts +116 -0
  111. package/.pi/lib/harness-spawn-topology.ts +121 -87
  112. package/.pi/lib/harness-subagent-submit-registry.ts +10 -0
  113. package/.pi/lib/harness-subagents-bridge.ts +4 -1
  114. package/.pi/lib/harness-ui-state.ts +95 -48
  115. package/.pi/lib/plan-approval/dialog.ts +5 -0
  116. package/.pi/lib/plan-approval/validate.ts +1 -1
  117. package/.pi/lib/plan-approval-readiness.ts +32 -0
  118. package/.pi/lib/plan-debate-gate.ts +154 -114
  119. package/.pi/lib/plan-task-clarification.ts +158 -0
  120. package/.pi/prompts/harness-auto.md +2 -2
  121. package/.pi/prompts/harness-ls-lint-steward.md +43 -0
  122. package/.pi/prompts/harness-plan.md +63 -13
  123. package/.pi/prompts/harness-review.md +44 -10
  124. package/.pi/prompts/harness-run.md +35 -13
  125. package/.pi/prompts/harness-sentrux-steward.md +2 -2
  126. package/.pi/prompts/harness-setup.md +74 -5
  127. package/.pi/prompts/harness-steer.md +6 -5
  128. package/.pi/prompts/wiki-save.md +5 -4
  129. package/.pi/scripts/README.md +8 -0
  130. package/.pi/scripts/generate-agents-policy-yaml.mjs +14 -2
  131. package/.pi/scripts/harness-auto-commit-bootstrap.mjs +96 -0
  132. package/.pi/scripts/harness-cli-verify.sh +47 -0
  133. package/.pi/scripts/harness-git-churn.mjs +77 -0
  134. package/.pi/scripts/harness-git-commit.mjs +173 -0
  135. package/.pi/scripts/harness-ls-lint-bootstrap.mjs +142 -0
  136. package/.pi/scripts/harness-ls-lint-cli.mjs +184 -0
  137. package/.pi/scripts/harness-seed-project-contracts.mjs +47 -0
  138. package/.pi/scripts/harness-sentrux-diagnostics.mjs +230 -0
  139. package/.pi/scripts/harness-sentrux-report.mjs +256 -0
  140. package/.pi/scripts/harness-verify.mjs +361 -125
  141. package/.pi/scripts/ls-lint-rules-sync.mjs +265 -0
  142. package/.pi/scripts/run-tests.mjs +1 -0
  143. package/.pi/settings.example.json +1 -0
  144. package/.sentrux/rules.toml +1 -1
  145. package/AGENTS.md +2 -0
  146. package/CHANGELOG.md +32 -0
  147. package/README.md +13 -4
  148. package/package.json +13 -6
  149. package/vendor/pi-vcc/src/hooks/before-compact.ts +86 -60
@@ -7,12 +7,13 @@ argument-hint: "[--run <run-id>] [--quick] [--readonly] [--trace <trace-ref>]"
7
7
 
8
8
  You are the **post-run verification PM** (PMBOK Monitoring and Controlling). Run measure → judge → red team in one command. Parent owns `ask_user`, deterministic scripts, `harness_artifact_ready`, and run ownership (`--claim` on resume). Subagents persist via **`submit_*`** only (no parent `write` to verdict artifacts).
9
9
 
10
- **Practice map:** `.pi/harness/docs/practice-map.md`
10
+ Follow the review sequence in this prompt directly: deterministic checks → benchmark evaluator → verdict evaluator → adversary → optional tie-breaker.
11
11
 
12
12
  Read **harness-orchestration** and **harness-review** skills before spawning.
13
13
 
14
14
  ## Allowed subagents
15
15
 
16
+ - `harness/sentrux-repair-advisor` (Phase 1b — structural repair plan from OSS diagnostics; before benchmark evaluator)
16
17
  - `harness/reviewing/evaluator` (`mode: benchmark` then `mode: verdict`)
17
18
  - `harness/reviewing/adversary` (independent red team)
18
19
  - `harness/reviewing/tie-breaker` (escalation only when adversary blocks and eval was `conditional_pass`; skip when `--quick`)
@@ -53,15 +54,24 @@ Ownership: this command **auto-claims** the run for the current Pi session unles
53
54
  node "$UP_PKG/.pi/scripts/harness-verify.mjs"
54
55
  ```
55
56
 
56
- When `HARNESS_SENTRUX_REQUIRED=true`, after verify succeeds:
57
+ **Sentrux single-scan rule:** run capture **once** per review unless `artifacts/sentrux-report.json` is missing or `HARNESS_SENTRUX_RESCAN=1`.
58
+
59
+ When `HARNESS_SENTRUX_REQUIRED=true` (or report missing), after verify succeeds:
57
60
 
58
61
  ```bash
59
- node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" gate
62
+ node "$UP_PKG/.pi/scripts/harness-sentrux-report.mjs" --out "<run_dir>" --run-id "<run_id>" --signal
63
+ node "$UP_PKG/.pi/scripts/harness-sentrux-diagnostics.mjs" --report "<run_dir>/artifacts/sentrux-report.json" --out "<run_dir>" --churn
60
64
  ```
61
65
 
62
- Compare to baseline from `/harness-run` (`harness-sentrux-cli.mjs gate --save`). The wrapper resolves the project root before invoking Sentrux so `.sentrux/rules.toml` is found from run directories. If CLI missing, record `gate_status: not_installed`.
66
+ Otherwise read existing `artifacts/sentrux-report.json`, `artifacts/sentrux-diagnostics.json`, and `artifacts/sentrux-signal.yaml` from `/harness-run`. If CLI missing (127), record `gate_status: not_installed`. Append or refresh session entry `harness-sentrux-signal`.
67
+
68
+ When `HARNESS_LS_LINT_REQUIRED=true`:
69
+
70
+ ```bash
71
+ node "$UP_PKG/.pi/scripts/harness-ls-lint-cli.mjs" --json
72
+ ```
63
73
 
64
- Ensure `artifacts/sentrux-signal.yaml` exists under the run dir (written during `/harness-run`). If missing, write it from the latest `sentrux check` / `gate` output. Append or refresh session entry `harness-sentrux-signal`.
74
+ Ensure `artifacts/ls-lint-signal.yaml` exists (from `/harness-run` or write from CLI output). Append or refresh `harness-ls-lint-signal`.
65
75
 
66
76
  Run project tests if the approved `PlanPacket` or spawn context lists a test command. Capture stdout paths only — do not paste full logs into the next spawn.
67
77
 
@@ -72,10 +82,34 @@ schema_version: "1.0.0"
72
82
  harness_verify: pass|fail
73
83
  sentrux_check: pass|fail|skipped|not_installed
74
84
  sentrux_gate: pass|degraded|skipped|not_installed
85
+ ls_lint: pass|fail|skipped|not_installed
86
+ ls_lint_violations: 0
75
87
  notes: "…"
76
88
  ```
77
89
 
78
- `harness_artifact_ready({ paths: ["artifacts/benchmark-log.yaml", "artifacts/sentrux-signal.yaml"] })` when written.
90
+ `harness_artifact_ready({ paths: ["artifacts/benchmark-log.yaml", "artifacts/sentrux-report.json", "artifacts/sentrux-diagnostics.json", "artifacts/sentrux-signal.yaml", "artifacts/ls-lint-signal.yaml"] })` when written.
91
+
92
+ ## Phase 1b — Sentrux repair advisor (subagent)
93
+
94
+ **Practice:** Close the loop from fitness-function observation to bounded repair directives. Skip when `artifacts/sentrux-repair-plan.yaml` already exists and `HARNESS_SENTRUX_RESCAN` is unset.
95
+
96
+ Spawn when **any**:
97
+
98
+ - `artifacts/sentrux-report.json` → `check.check_pass` is false, or
99
+ - `gate.status` is `degraded`, or
100
+ - `artifacts/sentrux-diagnostics.json` lists non-empty `diagnostics.complex_functions` or boundary/layer violations
101
+
102
+ ```
103
+ subagent({
104
+ agentScope: "both",
105
+ agent: "harness/sentrux-repair-advisor",
106
+ task: "<HarnessSpawnContext run_dir + plan_packet_path + paths: sentrux-report.json, sentrux-diagnostics.json, sentrux-signal.yaml — read only; emit repair plan>"
107
+ })
108
+ ```
109
+
110
+ Subagent calls **`submit_sentrux_repair_plan`** → `artifacts/sentrux-repair-plan.yaml`.
111
+
112
+ `harness_artifact_ready({ paths: ["artifacts/sentrux-repair-plan.yaml"] })` when written.
79
113
 
80
114
  ## Phase 2 — Measure actuals vs plan (benchmark evaluator)
81
115
 
@@ -85,7 +119,7 @@ notes: "…"
85
119
  subagent({
86
120
  agentScope: "both",
87
121
  agent: "harness/reviewing/evaluator",
88
- task: "<HarnessSpawnContext mode benchmark + plan_packet_path + run_dir + acceptance_checks + paths: benchmark-log.yaml, sentrux-signal.yaml — treat Sentrux fields as measured structural actuals, not executor goals>"
122
+ task: "<HarnessSpawnContext mode benchmark + plan_packet_path + run_dir + acceptance_checks + paths: benchmark-log.yaml, sentrux-signal.yaml, ls-lint-signal.yaml — treat Sentrux/ls-lint fields as measured structural actuals, not executor goals>"
89
123
  })
90
124
  ```
91
125
 
@@ -97,7 +131,7 @@ Gate:
97
131
  harness_artifact_ready({ paths: ["artifacts/eval-verdict.yaml"] })
98
132
  ```
99
133
 
100
- **Do not stop** after benchmark fail — continue to verdict (and adversary per tier) so `review-outcome.yaml` can route steer vs replan (ADR 0044).
134
+ **Do not stop** after benchmark fail — continue to verdict (and adversary per tier) so `review-outcome.yaml` can route steer vs replan.
101
135
 
102
136
  ## Phase 3 — Policy / quality audit (verdict evaluator)
103
137
 
@@ -119,7 +153,7 @@ Gate again with `harness_artifact_ready`.
119
153
 
120
154
  ## Phase 4 — Independent red team (adversary)
121
155
 
122
- **Practice:** Generator–evaluator separation; adversary distinct from measurer (ADR 0032).
156
+ **Practice:** Generator–evaluator separation; adversary stays distinct from the measurer.
123
157
 
124
158
  Skip when `--quick`. **Tiered steer:** full adversary on initial run + steer attempt 1; lite review (no adversary) on steer attempts 2+ unless prior `block_merge`.
125
159
 
@@ -151,7 +185,7 @@ subagent({ agentScope: "both", agent: "harness/reviewing/tie-breaker", task: "
151
185
 
152
186
  - **Never** parse subprocess JSON to write `eval-verdict.yaml` or `adversary-report.yaml` — use `submit_*` + `harness_artifact_ready` only.
153
187
  - Do not edit `plan-packet.yaml`.
154
- - Do not run inline review checks in this session (subagent isolation per ADR 0032).
188
+ - Do not run inline review checks in this session (keep review work isolated to subagents).
155
189
  - Same Pi session as `/harness-run` is preferred; `--claim` makes cross-session resume work.
156
190
 
157
191
  ## Phase 6 — Review outcome + repair brief (parent)
@@ -1,11 +1,10 @@
1
1
  ---
2
2
  description: Execute only against an approved PlanPacket with strict phase gates.
3
- argument-hint: ""
4
3
  ---
5
4
 
6
5
  # harness-run
7
6
 
8
- **Practice map:** `.pi/harness/docs/practice-map.md`
7
+ Follow this prompt's execution flow directly: baseline gate → executor spawn → structural observation → review handoff.
9
8
 
10
9
  You orchestrate the **Executing Process Group** — spawn `harness/running/executor` only. Do **not** implement inline.
11
10
 
@@ -38,6 +37,14 @@ The wrapper passes the resolved project root explicitly so Sentrux can find `.se
38
37
 
39
38
  Do **not** ask the executor to optimize Sentrux metrics — observation is for `/harness-review` only.
40
39
 
40
+ When `HARNESS_LS_LINT_REQUIRED=true`, record a pre-execute filename baseline:
41
+
42
+ ```bash
43
+ node "$UP_PKG/.pi/scripts/harness-ls-lint-cli.mjs" --json
44
+ ```
45
+
46
+ Note `violation_count` in run notes (do not block execute on pre-existing violations unless chair policy says otherwise).
47
+
41
48
  ## Orchestration — Single jelled implementer
42
49
 
43
50
  **Practice:** Peopleware — one accountable team owns delivery; generator–evaluator separation (executor does not self-certify).
@@ -58,33 +65,48 @@ subagent({ agentScope: "both", agent: "harness/running/executor", task: "<Harnes
58
65
 
59
66
  **Practice:** Monitoring actuals vs baseline — in-process fitness functions after generator work.
60
67
 
61
- After executor subprocess completes:
68
+ After executor subprocess completes, run **one** Sentrux capture (OSS CLI parse — no MCP/Pro):
69
+
70
+ ```bash
71
+ node "$UP_PKG/.pi/scripts/harness-sentrux-report.mjs" --out "<run_dir>" --run-id "<run_id>" --signal
72
+ node "$UP_PKG/.pi/scripts/harness-sentrux-diagnostics.mjs" --report "<run_dir>/artifacts/sentrux-report.json" --out "<run_dir>" --churn
73
+ ```
74
+
75
+ - If `sentrux-report.json` → `check.check_pass` is false or `gate.status` is `degraded` → set `execution_status: scope_drift` (or `blocked` if unrecoverable); parent runs **`/harness-review`** next (not immediate replan).
76
+ - `harness-sentrux-report.mjs --signal` writes `artifacts/sentrux-signal.yaml` (schema `1.1.0`) with `report_path`, `diagnostics_path`, `quality_signal`, `violation_count`, `degraded_reasons` when present.
77
+ - If `sentrux` is not installed (exit 127), record `gate_status: not_installed` via minimal `write_harness_yaml` and continue.
78
+
79
+ Append session custom entry `harness-sentrux-signal` mirroring the signal file (observation bus / telemetry).
80
+
81
+ `harness_artifact_ready({ paths: ["artifacts/sentrux-report.json", "artifacts/sentrux-diagnostics.json", "artifacts/sentrux-signal.yaml"] })` when written.
82
+
83
+ When `HARNESS_LS_LINT_REQUIRED=true`, after executor completes:
62
84
 
63
85
  ```bash
64
- node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" check
65
- node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" gate
86
+ node "$UP_PKG/.pi/scripts/harness-ls-lint-cli.mjs" --json
66
87
  ```
67
88
 
68
- - If `sentrux check` exits non-zero or `gate` reports degradation set `execution_status: scope_drift` (or `blocked` if unrecoverable); parent runs **`/harness-review`** next (not immediate replan).
69
- - Write `artifacts/sentrux-signal.yaml` via `write_harness_yaml`:
89
+ - If `lint_pass` is falseinclude in `validation_summary`; prefer `scope_drift` when new violations vs pre-run baseline.
90
+ - Write `artifacts/ls-lint-signal.yaml` via `write_harness_yaml`:
70
91
 
71
92
  ```yaml
72
93
  schema_version: "1.0.0"
73
94
  run_id: "<run_id>"
74
- check_pass: true|false
75
- gate_status: pass|degraded|skipped|not_installed
76
- quality_signal_summary: "<one line from CLI output>"
95
+ lint_pass: true|false
96
+ violation_count: 0
97
+ status: pass|fail|skipped|not_installed
98
+ quality_signal_summary: "<one line>"
77
99
  recorded_at: "<ISO8601>"
78
100
  phase: execute
79
101
  ```
80
102
 
81
- - Append session custom entry `harness-sentrux-signal` with the same fields (observation bus / telemetry).
103
+ - Append session custom entry `harness-ls-lint-signal` with the same fields.
82
104
 
83
- `harness_artifact_ready({ paths: ["artifacts/sentrux-signal.yaml"] })` when written.
105
+ `harness_artifact_ready({ paths: ["artifacts/ls-lint-signal.yaml"] })` when written.
84
106
 
85
107
  ## Parent rules
86
108
 
87
- - On `scope_drift`, finish handoff and recommend **`/harness-review`** (review classifies `plan_gap` vs `implementation_gap` ADR 0044).
109
+ - On `scope_drift`, finish handoff and recommend **`/harness-review`** (review classifies whether the gap is planning or implementation).
88
110
  - Do not call `ask_user` for plan-level ambiguity — return to plan command.
89
111
 
90
112
  ## Completion
@@ -39,14 +39,14 @@ Gate: `harness_artifact_ready({ paths: ["artifacts/sentrux-manifest-proposal.yam
39
39
  Read `artifacts/sentrux-manifest-proposal.yaml`.
40
40
 
41
41
  - `change_class: none` → report no manifest change; stop.
42
- - Otherwise → `ask_user` with summary, evidence bullets, and `adr_draft` if `adr_required`.
42
+ - Otherwise → `ask_user` with summary, evidence bullets, and any draft decision text when a formal decision record is required.
43
43
 
44
44
  On approval:
45
45
 
46
46
  1. Apply `manifest_patch` to `.pi/harness/sentrux/architecture.manifest.json` (parent `write` or manual edit).
47
47
  2. `node "$UP_PKG/.pi/scripts/harness-sentrux-bootstrap.mjs" --force`
48
48
  3. Append session custom entry `harness-architecture-changed` (triggers rules sync extension).
49
- 4. If `adr_required`, file harness ADR snippet or `docs/adr/` entry per team convention.
49
+ 4. If a formal decision record is required, file it in the target project's standard decision-log location.
50
50
 
51
51
  On reject: keep manifest unchanged; document decision in run notes.
52
52
 
@@ -15,11 +15,12 @@ Bootstraps the complete ultimate-pi agentic harness: Graphify knowledge graph, C
15
15
  |---------|------------------|
16
16
  | `UP_PKG="$(pwd)"` in an **external** repo | Wrong — scripts live in the npm package. Resolve via `harness-resolve-up-pkg.mjs` (see Step 0). |
17
17
  | Re-running 2.1–2.8 manually after CLI verify | Wasteful — trust `harness-cli-verify.sh` output; only fix reported ✗ lines. |
18
- | Overwriting `AGENTS.md` after graphify | Graphify appends a section — **merge**, do not replace (Step 4.3). |
18
+ | Overwriting `AGENTS.md` after graphify | Graphify appends a section — **merge**, do not replace (Step 4.5). |
19
19
  | `sentrux-rules-sync` without project manifest | Use **`harness-sentrux-bootstrap.mjs`** (Step 4.2) — seeds manifest + idempotent rules sync. |
20
20
  | Re-running bootstrap with `--force` on unchanged manifest | Wasteful but safe — default bootstrap skips when hash unchanged; `--force` only after manifest edits. |
21
21
  | `graph.json` uses `links`, not `edges` | Step 6 stats: `g.get('edges', g.get('links', []))`. |
22
22
  | Guessing harness-web / `.env` defaults when `ask_user` is available | **Mandatory `ask_user`** at Step 4.0 unless `--non-interactive`. |
23
+ | WSL2 / SSH without WebView | Set `HARNESS_ASK_USER_UI=tui` in project `.env` (or rely on `auto` TUI fallback). Glimpse needs a display (WSLg or X11). |
23
24
  | `sudo apt-get` without passwordless sudo | Skip — report manual fix; do not block the rest of setup. |
24
25
  | `graphify codex install` | **Never run** — it writes `.codex/hooks.json`. Harness targets pi only (`graphify install --platform pi`). |
25
26
  | Overwriting `.env` | Use `harness-sync-env.mjs` — never rewrite; append missing keys only. |
@@ -155,7 +156,7 @@ bash "$UP_PKG/.pi/scripts/harness-cli-verify.sh"
155
156
  # Reinstall everything: bash "$UP_PKG/.pi/scripts/harness-cli-verify.sh" --force
156
157
  ```
157
158
 
158
- **Required (script must exit 0):** scrapling + harness-web smoke, ctx7, ast-grep (`sg`), sentrux (when harness manifest present).
159
+ **Required (script must exit 0):** scrapling + harness-web smoke, ctx7, ast-grep (`sg`), sentrux (when harness manifest present), ls-lint (when naming manifest present).
159
160
 
160
161
  **Warnings allowed:** biome (optional; skipped for non-JS/TS repos or if install fails), gh (if not authenticated), agent-browser (if OS libs need manual `sudo apt-get install`), cocoindex-code (empty corpus on tiny repos; first `[full]` install downloads local embedding model).
161
162
 
@@ -288,7 +289,7 @@ Quick smoke test:
288
289
  sg -p 'function $NAME($$$ARGS) { $$$BODY }' --json 2>/dev/null | head -5 && echo "✓ ast-grep pattern matching works" || echo "! ast-grep smoke test — may need language-specific config"
289
290
  ```
290
291
 
291
- ### 2.7 — gh CLI (GitHub Issues Spec Storage — ADR-025)
292
+ ### 2.7 — gh CLI (GitHub Issues Spec Storage)
292
293
 
293
294
  ```bash
294
295
  if ! command -v gh &>/dev/null || [ "$FORCE" = "true" ]; then
@@ -326,9 +327,15 @@ sentrux plugin add-standard 2>/dev/null || echo "Plugins already installed or fa
326
327
 
327
328
  **Rules.toml bootstrap runs in Step 4.2** (idempotent, merge-safe). Sentrux CLI workflows use the package **`sentrux`** skill (`.agents/skills/sentrux`); no symlink into `.pi/skills/` required.
328
329
 
330
+ ### 2.9 — ls-lint (Filename / Directory Naming)
331
+
332
+ Installed and smoke-tested by `harness-cli-verify.sh` (`npm install -g @ls-lint/ls-lint@2.3.1`).
333
+
334
+ **`.ls-lint.yml` bootstrap runs in Step 4.3** (idempotent, merge-safe). Use skill **`harness-ls-lint-setup`**; sync via `/harness-ls-lint-sync` in pi.
335
+
329
336
  ## Step 3 — Pi Extension Packages
330
337
 
331
- Bundled extensions load from the installed `ultimate-pi` package. The harness lens wrapper at `.pi/extensions/harness-lens.ts` loads `.pi/extensions/lib/harness-lens/` for edit autopatch, secrets blocking, deferred format, and LSP tools. Structural search uses shell `sg` (installed globally by setup); architecture gates use Sentrux. See [ADR 0045](.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md).
338
+ Bundled extensions load from the installed `ultimate-pi` package. The harness lens wrapper at `.pi/extensions/harness-lens.ts` loads `.pi/extensions/lib/harness-lens/` for edit autopatch, secrets blocking, deferred format, and LSP tools. Structural search uses shell `sg` (installed globally by setup); architecture gates use Sentrux.
332
339
 
333
340
  Harness lens findings are **complementary** to Sentrux:
334
341
 
@@ -454,6 +461,18 @@ Rules:
454
461
  - Re-runs only add keys from `$UP_PKG/.pi/harness/env.harness.template` that are absent (managed block at EOF).
455
462
  - Ensure `.env` is gitignored (Step 4.1).
456
463
 
464
+ ### 4.0c — ask_user UI (optional)
465
+
466
+ Harness `ask_user` supports terminal (TUI), headless (CI), and Glimpse WebView (`HARNESS_ASK_USER_UI=auto|tui|glimpse|headless`). Dependencies install with `.pi/npm` during pi package install.
467
+
468
+ | Environment | Recommendation |
469
+ |-------------|----------------|
470
+ | **WSL2 without WSLg / no DISPLAY** | `HARNESS_ASK_USER_UI=tui` in `.env` (default `auto` already falls back) |
471
+ | **Desktop Linux / macOS / WSLg** | `auto` or `glimpse` for richer questionnaires |
472
+ | **CI / `--non-interactive`** | Prompts skipped; do not expect WebView |
473
+
474
+ Append `HARNESS_ASK_USER_UI=tui` to `.env` when WebView is unavailable. The first real `ask_user` reports `ui_backend` and `ui_degraded` in tool details.
475
+
457
476
  Template keys (placeholders — user fills secrets): `HARNESS_TELEMETRY_ENABLED`, `HARNESS_WEB_*`, `HARNESS_VCC_COMPACTION`, `HARNESS_VCC_DEBUG`, plus commented optional PostHog / Graphify vars.
458
477
 
459
478
  ### 4.1 — .gitignore Entries
@@ -484,6 +503,10 @@ Ensure `.gitignore` contains harness runtime entries (see repo root `.gitignore`
484
503
  .sentrux/*
485
504
  !.sentrux/
486
505
  !.sentrux/rules.toml
506
+
507
+ # ls-lint sync meta (.ls-lint.yml is committed)
508
+ .ls-lint/*
509
+ !.ls-lint/
487
510
  ```
488
511
 
489
512
  ### 4.2 — Sentrux rules bootstrap (required)
@@ -521,7 +544,52 @@ Set up structural regression baseline (optional):
521
544
  node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" gate --save 2>/dev/null || echo "Baseline will be saved on first gate run"
522
545
  ```
523
546
 
524
- ### 4.3 — Project AGENTS.md
547
+ ### 4.3 — ls-lint naming bootstrap (required)
548
+
549
+ **Skill:** invoke **harness-ls-lint-setup** before hand-editing `.ls-lint.yml` or `naming.manifest.json`.
550
+
551
+ From **project root**, run the bundled bootstrap (seeds manifest when missing, syncs `.ls-lint.yml` without clobbering custom YAML):
552
+
553
+ ```bash
554
+ node "$UP_PKG/.pi/scripts/harness-ls-lint-bootstrap.mjs"
555
+ # After editing naming.manifest.json:
556
+ node "$UP_PKG/.pi/scripts/harness-ls-lint-bootstrap.mjs" --force
557
+ # In pi: /harness-ls-lint-sync (always --force sync)
558
+ ```
559
+
560
+ | Command | When |
561
+ |---------|------|
562
+ | `harness-ls-lint-bootstrap.mjs` (no flags) | `/harness-setup`, first install, re-run safe |
563
+ | `harness-ls-lint-bootstrap.mjs --force` | Manifest rules/ignores changed |
564
+ | `ls-lint-rules-sync.mjs --check` | CI / harness-verify drift only |
565
+ | `harness-ls-lint-cli.mjs` | Root-resolving filename checks from harness run dirs |
566
+ | `/harness-ls-lint-sync` | Interactive re-sync from pi |
567
+
568
+ Verify naming:
569
+
570
+ ```bash
571
+ node "$UP_PKG/.pi/scripts/harness-ls-lint-cli.mjs" && echo "✓ ls-lint pass" || echo "✗ ls-lint failed"
572
+ ```
573
+
574
+ ### 4.4 — Auto-commit co-author bootstrap (required)
575
+
576
+ **Skill:** invoke **harness-git-commit** before any agent commit.
577
+
578
+ From **project root**:
579
+
580
+ ```bash
581
+ node "$UP_PKG/.pi/scripts/harness-auto-commit-bootstrap.mjs"
582
+ ```
583
+
584
+ | Command | When |
585
+ |---------|------|
586
+ | `harness-auto-commit-bootstrap.mjs` | `/harness-setup`, first install, re-run safe |
587
+ | `harness-git-commit.mjs --dry-run --subject "…"` | Preview message + trailer |
588
+ | `harness-git-commit.mjs --type … --scope … --subject "…"` | Commit after `git add` |
589
+
590
+ Edit `.pi/auto-commit.json` to customize `message.template` or `coAuthor` (project overrides package defaults).
591
+
592
+ ### 4.5 — Project AGENTS.md
525
593
 
526
594
  **Do not overwrite** an existing `AGENTS.md` — graphify bootstrap may have appended a `## Graphify` section. If missing, create minimal onboarding content; if present, only add harness subsections that are absent.
527
595
 
@@ -652,6 +720,7 @@ Output summary table:
652
720
  | ast-grep | ✓/✗ | AST-aware code search (`sg`)
653
721
  | gh CLI | ✓/✗ | Auth: yes/no |
654
722
  | sentrux | ✓/✗ | CLI + plugins; rules via Step 4.2 bootstrap |
723
+ | ls-lint | ✓/✗ | CLI; `.ls-lint.yml` via Step 4.3 bootstrap |
655
724
  | Sentrux rules.toml | ✓/✗ | `.sentrux/rules.toml` synced from manifest |
656
725
  | pi extensions | ✓/✗ | bundled extensions + harness lens wrapper |
657
726
  | harness lens | ✓/✗ | `.pi/extensions/harness-lens.ts`; PostHog owns lens telemetry; complements Sentrux architecture signal |
@@ -5,7 +5,7 @@ argument-hint: "[--attempt N]"
5
5
 
6
6
  # harness-steer
7
7
 
8
- Thin orchestrator for the **steer loop** (ADR 0044). Run only after `/harness-review` produced `artifacts/review-outcome.yaml` and `artifacts/repair-brief.yaml` with `remediation_class: implementation_gap`.
8
+ Thin orchestrator for the **steer loop**. Run only after `/harness-review` produced `artifacts/review-outcome.yaml` and `artifacts/repair-brief.yaml` with `remediation_class: implementation_gap`.
9
9
 
10
10
  ## Preconditions
11
11
 
@@ -15,13 +15,14 @@ Thin orchestrator for the **steer loop** (ADR 0044). Run only after `/harness-re
15
15
 
16
16
  ## Steps
17
17
 
18
- 1. Read `artifacts/review-outcome.yaml`, `artifacts/repair-brief.yaml`, `plan_packet_path` (paths only — do not paste bodies into tool args).
18
+ 1. Read `artifacts/review-outcome.yaml`, `artifacts/repair-brief.yaml`, `plan_packet_path` (paths only — do not paste bodies into tool args). When present, `repair-brief.yaml` already merges `artifacts/sentrux-repair-plan.yaml` (`[sentrux:…]` directives).
19
19
  2. Update `artifacts/steer-state.yaml` (`attempt`, `max_attempts`, `active: true`).
20
20
  3. Set policy phase to **execute** before spawning executor (required for mutating tools).
21
21
  4. One `ask_user` steer gate unless `run-context.steer_approved` is already true.
22
- 5. Spawn **`harness/running/executor`** with `HarnessSpawnContext.mode: repair` and `repair_brief_path: artifacts/repair-brief.yaml`. Repair uses the same hash-anchored `read`/`edit`, batching, and pre-handoff verification rules as `/harness-run` (ADR 0051).
23
- 6. Optional: `node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" gate --save` after repair to refresh baseline (ADR 0044).
24
- 7. `next_command`: **`/harness-review`** (always re-verify; tiered adversary on attempts 2+ per practice-map).
22
+ 5. Spawn **`harness/running/executor`** with `HarnessSpawnContext.mode: repair` and `repair_brief_path: artifacts/repair-brief.yaml`. Repair uses the same hash-anchored `read`/`edit`, batching, and pre-handoff verification rules as `/harness-run`.
23
+ 6. Optional: `node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" gate --save` after repair to refresh the structural baseline.
24
+ 7. Optional: `node "$UP_PKG/.pi/scripts/harness-ls-lint-cli.mjs"` after repair to confirm filename conventions.
25
+ 7. `next_command`: **`/harness-review`** (always re-verify; use tiered adversary on attempts 2+).
25
26
 
26
27
  ## Forbidden
27
28
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: Save the current conversation or a specific insight as a structured note in the knowledge graph.
3
+ argument-hint: "[name|session|decision <name>]"
3
4
  ---
4
5
 
5
6
  Read the `graphify` skill for context on graphify-out/ structure.
@@ -9,10 +10,10 @@ so it can be graphified and queried. Then run `graphify ./raw --update` to
9
10
  incorporate it into the knowledge graph.
10
11
 
11
12
  Usage:
12
- - `/save` — analyze the full conversation and save the most valuable content
13
- - `/save [name]` — save with a specific note title
14
- - `/save session` — save a complete session summary
15
- - `/save decision [name]` — save as a design/governance decision (also mirror into `.pi/harness/incidents/` when incident tracking is required)
13
+ - `/wiki-save` — analyze the full conversation and save the most valuable content
14
+ - `/wiki-save [name]` — save with a specific note title
15
+ - `/wiki-save session` — save a complete session summary
16
+ - `/wiki-save decision [name]` — save as a design/governance decision (also mirror into `.pi/harness/incidents/` when incident tracking is required)
16
17
 
17
18
  Save to: `./raw/[sanitized-name].md`
18
19
  Then: `graphify ./raw --update`
@@ -28,7 +28,15 @@ From **Typescript extensions**, use `resolveHarnessScript()` / `getHarnessPackag
28
28
  | Sentrux rules re-sync after manifest edit | `node "$UP_PKG/.pi/scripts/harness-sentrux-bootstrap.mjs" --force` or `/harness-sentrux-sync` |
29
29
  | Sentrux rules drift check (CI) | `node "$UP_PKG/.pi/scripts/sentrux-rules-sync.mjs" --check` |
30
30
  | Sentrux run/review check or gate (root-resolving) | `node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" check` / `gate [--save]` |
31
+ | Sentrux single-scan report + signal (ADR 0052) | `node "$UP_PKG/.pi/scripts/harness-sentrux-report.mjs" --out <run_dir> --run-id <id> --signal` |
32
+ | Sentrux diagnostics synthesis | `node "$UP_PKG/.pi/scripts/harness-sentrux-diagnostics.mjs" --report <run_dir>/artifacts/sentrux-report.json --out <run_dir> [--churn]` |
33
+ | ls-lint naming bootstrap (harness-setup) | `node "$UP_PKG/.pi/scripts/harness-ls-lint-bootstrap.mjs"` |
34
+ | ls-lint naming re-sync after manifest edit | `node "$UP_PKG/.pi/scripts/harness-ls-lint-bootstrap.mjs" --force` or `/harness-ls-lint-sync` |
35
+ | ls-lint config drift check (CI) | `node "$UP_PKG/.pi/scripts/ls-lint-rules-sync.mjs" --check` |
36
+ | ls-lint filename check (root-resolving) | `node "$UP_PKG/.pi/scripts/harness-ls-lint-cli.mjs` [`--json`] |
31
37
  | Resolve package root (`UP_PKG`) | `node "$UP_PKG/.pi/scripts/harness-resolve-up-pkg.mjs"` |
38
+ | Auto-commit config bootstrap | `node "$UP_PKG/.pi/scripts/harness-auto-commit-bootstrap.mjs"` |
39
+ | Git commit + co-author trailer | `node "$UP_PKG/.pi/scripts/harness-git-commit.mjs" --subject "…"` [`--dry-run`] |
32
40
  | Project `.env` (append-only) | `node "$UP_PKG/.pi/scripts/harness-sync-env.mjs"` (`--create-missing` after user confirms) |
33
41
  | Harness lens extension | `.pi/extensions/harness-lens.ts` → `.pi/lib/harness-lens/index.ts` (loaded by `.pi/extensions`; PostHog owns lens telemetry) |
34
42
 
@@ -32,6 +32,8 @@ const SUBMIT_BY_AGENT = {
32
32
  "harness/trace-librarian": ["submit_human_required"],
33
33
  "harness/incident-recorder": ["submit_human_required"],
34
34
  "harness/sentrux-steward": ["submit_sentrux_manifest_proposal"],
35
+ "harness/sentrux-repair-advisor": ["submit_sentrux_repair_plan"],
36
+ "harness/ls-lint-steward": ["submit_ls_lint_manifest_proposal"],
35
37
  };
36
38
 
37
39
  function parseFrontmatter(content) {
@@ -48,7 +50,12 @@ function kindFor(id) {
48
50
  if (id === "harness/reviewing/tie-breaker") return "tie_breaker";
49
51
  if (id === "harness/trace-librarian") return "trace";
50
52
  if (id === "harness/incident-recorder") return "incident";
51
- if (id === "harness/sentrux-steward" || id === "harness/sentrux-bootstrap")
53
+ if (id === "harness/sentrux-repair-advisor") return "evaluator";
54
+ if (
55
+ id === "harness/sentrux-steward" ||
56
+ id === "harness/sentrux-bootstrap" ||
57
+ id === "harness/ls-lint-steward"
58
+ )
52
59
  return "planner";
53
60
  return "other";
54
61
  }
@@ -79,7 +86,12 @@ async function main() {
79
86
 
80
87
  const kinds = {
81
88
  planner: { tools: KIND_BASE.planner, extensions: false, read_only: true },
82
- executor: { tools: KIND_BASE.executor, extensions: true, read_only: false },
89
+ executor: {
90
+ tools: KIND_BASE.executor,
91
+ extensions: true,
92
+ extension_bundle: "executor",
93
+ read_only: false,
94
+ },
83
95
  evaluator: { tools: KIND_BASE.evaluator, extensions: false, read_only: true },
84
96
  adversary: { tools: KIND_BASE.adversary, extensions: false, read_only: true },
85
97
  tie_breaker: {
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Idempotent auto-commit config bootstrap for harness projects.
4
+ *
5
+ * Seeds PROJECT/.pi/auto-commit.json from the ultimate-pi package template when missing.
6
+ *
7
+ * Usage:
8
+ * node "$UP_PKG/.pi/scripts/harness-auto-commit-bootstrap.mjs" [PROJECT_ROOT] [--check]
9
+ */
10
+
11
+ import { readFile, writeFile, mkdir, access, copyFile } from "node:fs/promises";
12
+ import { constants } from "node:fs";
13
+ import { join, dirname, basename } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ import { validateAutoCommitConfig } from "../lib/harness-auto-commit-config.mjs";
16
+
17
+ const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
18
+ const UP_PKG = join(SCRIPT_DIR, "..", "..");
19
+
20
+ const args = process.argv.slice(2).filter((a) => !a.startsWith("-"));
21
+ const checkOnly = process.argv.includes("--check");
22
+ const PROJECT_ROOT = args[0] || process.cwd();
23
+ const CONFIG_PATH = join(PROJECT_ROOT, ".pi", "auto-commit.json");
24
+ const TEMPLATE_PATH = join(UP_PKG, ".pi", "auto-commit.json");
25
+
26
+ async function fileExists(path) {
27
+ try {
28
+ await access(path, constants.R_OK);
29
+ return true;
30
+ } catch {
31
+ return false;
32
+ }
33
+ }
34
+
35
+ async function resolveScopeDefault(root) {
36
+ const pkgPath = join(root, "package.json");
37
+ if (await fileExists(pkgPath)) {
38
+ try {
39
+ const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
40
+ if (typeof pkg.name === "string" && pkg.name.trim()) {
41
+ return pkg.name.trim().replace(/^@/, "").split("/").pop() ?? pkg.name;
42
+ }
43
+ } catch {
44
+ /* ignore */
45
+ }
46
+ }
47
+ return basename(root) || "project";
48
+ }
49
+
50
+ async function main() {
51
+ if (!(await fileExists(TEMPLATE_PATH))) {
52
+ console.error(
53
+ "harness-auto-commit-bootstrap: missing package template",
54
+ TEMPLATE_PATH,
55
+ );
56
+ process.exit(1);
57
+ }
58
+
59
+ if (await fileExists(CONFIG_PATH)) {
60
+ if (checkOnly) {
61
+ const config = JSON.parse(await readFile(CONFIG_PATH, "utf-8"));
62
+ validateAutoCommitConfig(config);
63
+ console.log(`harness-auto-commit-bootstrap: ok ${CONFIG_PATH}`);
64
+ return;
65
+ }
66
+ console.log(
67
+ "harness-auto-commit-bootstrap: config present (edit .pi/auto-commit.json to customize)",
68
+ );
69
+ return;
70
+ }
71
+
72
+ if (checkOnly) {
73
+ console.error(
74
+ `harness-auto-commit-bootstrap: missing ${CONFIG_PATH} (run without --check to seed)`,
75
+ );
76
+ process.exit(1);
77
+ }
78
+
79
+ await mkdir(dirname(CONFIG_PATH), { recursive: true });
80
+ await copyFile(TEMPLATE_PATH, CONFIG_PATH);
81
+ const config = JSON.parse(await readFile(CONFIG_PATH, "utf-8"));
82
+ const scope = await resolveScopeDefault(PROJECT_ROOT);
83
+ if (config.message && typeof config.message === "object") {
84
+ config.message.scopeDefault = scope;
85
+ }
86
+ validateAutoCommitConfig(config);
87
+ await writeFile(CONFIG_PATH, `${JSON.stringify(config, null, "\t")}\n`, "utf-8");
88
+ console.log(
89
+ `harness-auto-commit-bootstrap: seeded -> ${CONFIG_PATH} (message.scopeDefault: ${scope})`,
90
+ );
91
+ }
92
+
93
+ main().catch((err) => {
94
+ console.error(err);
95
+ process.exit(1);
96
+ });
@@ -324,6 +324,37 @@ verify_gh() {
324
324
  fi
325
325
  }
326
326
 
327
+ verify_ls_lint() {
328
+ log "[ls-lint]"
329
+ npm_global_install "@ls-lint/ls-lint@2.3.1" "ls-lint" || {
330
+ fail "ls-lint npm install"
331
+ return
332
+ }
333
+ if ! ls-lint --version &>/dev/null; then
334
+ fail "ls-lint --version failed"
335
+ return
336
+ fi
337
+ _bootstrap="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/harness-ls-lint-bootstrap.mjs"
338
+ if [ -f "$_bootstrap" ]; then
339
+ node "$_bootstrap" --force 2>/dev/null ||
340
+ warn "ls-lint bootstrap failed (see harness-ls-lint-setup skill)"
341
+ fi
342
+ _cli="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/harness-ls-lint-cli.mjs"
343
+ if [ -f "$_cli" ]; then
344
+ if node "$_cli" 2>/dev/null; then
345
+ pass "ls-lint $(ls-lint --version 2>/dev/null | head -1)"
346
+ else
347
+ fail "ls-lint filename check failed (fix violations or tune naming.manifest.json)"
348
+ fi
349
+ else
350
+ if ls-lint 2>/dev/null; then
351
+ pass "ls-lint $(ls-lint --version 2>/dev/null | head -1)"
352
+ else
353
+ fail "ls-lint check failed"
354
+ fi
355
+ fi
356
+ }
357
+
327
358
  verify_sentrux() {
328
359
  log "[sentrux]"
329
360
  if ! have_cmd sentrux || [ "$FORCE" = true ]; then
@@ -361,7 +392,23 @@ verify_cocoindex
361
392
  verify_biome
362
393
  verify_sg
363
394
  verify_gh
395
+ verify_auto_commit() {
396
+ log "[auto-commit]"
397
+ _git_commit="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/harness-git-commit.mjs"
398
+ if [ ! -f "$_git_commit" ]; then
399
+ warn "harness-git-commit.mjs missing (package incomplete)"
400
+ return
401
+ fi
402
+ if node "$_git_commit" --print-message --subject "harness-cli-verify" 2>/dev/null | grep -qi 'Co-authored-by:'; then
403
+ pass "harness-git-commit (co-author trailer)"
404
+ else
405
+ fail "harness-git-commit --print-message missing Co-authored-by trailer"
406
+ fi
407
+ }
408
+
364
409
  verify_sentrux
410
+ verify_ls_lint
411
+ verify_auto_commit
365
412
 
366
413
  log ""
367
414
  if [ "$FAILURES" -gt 0 ]; then