@dommaker/harness 1.8.1 → 1.10.0
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.
- package/CHANGELOG.md +16 -0
- package/README.md +10 -13
- package/dist/cli/commands/check.d.ts +3 -3
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +41 -78
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/constraints-report.d.ts +2 -10
- package/dist/cli/commands/constraints-report.d.ts.map +1 -1
- package/dist/cli/commands/constraints-report.js +4 -57
- package/dist/cli/commands/constraints-report.js.map +1 -1
- package/dist/cli/commands/constraints-retire.d.ts +9 -23
- package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
- package/dist/cli/commands/constraints-retire.js +39 -121
- package/dist/cli/commands/constraints-retire.js.map +1 -1
- package/dist/cli/commands/constraints.d.ts +3 -8
- package/dist/cli/commands/constraints.d.ts.map +1 -1
- package/dist/cli/commands/constraints.js +8 -23
- package/dist/cli/commands/constraints.js.map +1 -1
- package/dist/cli/commands/definitions.js +2 -2
- package/dist/cli/commands/init.d.ts +0 -32
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +7 -149
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +14 -17
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/scaffold-templates.d.ts +0 -2
- package/dist/cli/commands/scaffold-templates.d.ts.map +1 -1
- package/dist/cli/commands/scaffold-templates.js +2 -37
- package/dist/cli/commands/scaffold-templates.js.map +1 -1
- package/dist/cli/commands/scaffold.d.ts +0 -2
- package/dist/cli/commands/scaffold.d.ts.map +1 -1
- package/dist/cli/commands/scaffold.js +0 -10
- package/dist/cli/commands/scaffold.js.map +1 -1
- package/dist/cli/commands/status.js +10 -10
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/sync-docs/agents-syncer.d.ts +0 -2
- package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/agents-syncer.js +4 -23
- package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +22 -0
- package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/capabilities-syncer.js +113 -8
- package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/index.js +36 -4
- package/dist/cli/commands/sync-docs/index.js.map +1 -1
- package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
- package/dist/core/constraints/capabilities-parser.js +16 -4
- package/dist/core/constraints/capabilities-parser.js.map +1 -1
- package/dist/core/constraints/checker.d.ts +15 -24
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +33 -72
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/checkers/docs-freshness.js +1 -1
- package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.d.ts +2 -1
- package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.js +4 -3
- package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
- package/dist/core/constraints/checkers/index.d.ts +1 -1
- package/dist/core/constraints/checkers/index.d.ts.map +1 -1
- package/dist/core/constraints/checkers/index.js +4 -8
- package/dist/core/constraints/checkers/index.js.map +1 -1
- package/dist/core/constraints/checkers/iron-flags.d.ts +3 -4
- package/dist/core/constraints/checkers/iron-flags.d.ts.map +1 -1
- package/dist/core/constraints/checkers/iron-flags.js +4 -5
- package/dist/core/constraints/checkers/iron-flags.js.map +1 -1
- package/dist/core/constraints/checkers/no-test-simplification.js +1 -1
- package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -1
- package/dist/core/constraints/checkers/types.d.ts +1 -1
- package/dist/core/constraints/checkers/types.js +1 -1
- package/dist/core/constraints/definitions/guidelines.d.ts +4 -4
- package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
- package/dist/core/constraints/definitions/guidelines.js +9 -25
- package/dist/core/constraints/definitions/guidelines.js.map +1 -1
- package/dist/core/constraints/definitions/iron-laws.d.ts +4 -4
- package/dist/core/constraints/definitions/iron-laws.d.ts.map +1 -1
- package/dist/core/constraints/definitions/iron-laws.js +10 -81
- package/dist/core/constraints/definitions/iron-laws.js.map +1 -1
- package/dist/core/constraints/definitions.d.ts +7 -9
- package/dist/core/constraints/definitions.d.ts.map +1 -1
- package/dist/core/constraints/definitions.js +13 -16
- package/dist/core/constraints/definitions.js.map +1 -1
- package/dist/core/constraints/index.d.ts +2 -5
- package/dist/core/constraints/index.d.ts.map +1 -1
- package/dist/core/constraints/index.js +3 -13
- package/dist/core/constraints/index.js.map +1 -1
- package/dist/core/constraints/injection-writer.d.ts +10 -38
- package/dist/core/constraints/injection-writer.d.ts.map +1 -1
- package/dist/core/constraints/injection-writer.js +17 -54
- package/dist/core/constraints/injection-writer.js.map +1 -1
- package/dist/core/constraints/run-env.d.ts +1 -10
- package/dist/core/constraints/run-env.d.ts.map +1 -1
- package/dist/core/constraints/run-env.js +1 -22
- package/dist/core/constraints/run-env.js.map +1 -1
- package/dist/core/constraints/usage-report.d.ts +5 -7
- package/dist/core/constraints/usage-report.d.ts.map +1 -1
- package/dist/core/constraints/usage-report.js +5 -10
- package/dist/core/constraints/usage-report.js.map +1 -1
- package/dist/core/effective-constraints.d.ts +12 -22
- package/dist/core/effective-constraints.d.ts.map +1 -1
- package/dist/core/effective-constraints.js +13 -30
- package/dist/core/effective-constraints.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -9
- package/dist/core/index.js.map +1 -1
- package/dist/core/project-config-loader.d.ts +4 -42
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +16 -125
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/core/validators/passes-gate.d.ts +2 -2
- package/dist/core/validators/passes-gate.js +6 -6
- package/dist/core/validators/passes-gate.js.map +1 -1
- package/dist/hooks/bootstrap.d.ts +9 -12
- package/dist/hooks/bootstrap.d.ts.map +1 -1
- package/dist/hooks/bootstrap.js +9 -31
- package/dist/hooks/bootstrap.js.map +1 -1
- package/dist/hooks/index.d.ts +5 -7
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +4 -10
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +9 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -23
- package/dist/index.js.map +1 -1
- package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
- package/dist/monitoring/trace-analyzer.js +11 -12
- package/dist/monitoring/trace-analyzer.js.map +1 -1
- package/dist/monitoring/traces.d.ts +4 -4
- package/dist/monitoring/traces.d.ts.map +1 -1
- package/dist/monitoring/traces.js +8 -8
- package/dist/monitoring/traces.js.map +1 -1
- package/dist/presets/standard.d.ts +8 -10
- package/dist/presets/standard.d.ts.map +1 -1
- package/dist/presets/standard.js +10 -16
- package/dist/presets/standard.js.map +1 -1
- package/dist/types/constraint.d.ts +24 -35
- package/dist/types/constraint.d.ts.map +1 -1
- package/dist/types/constraint.js +8 -7
- package/dist/types/constraint.js.map +1 -1
- package/dist/types/passes-gate.d.ts +5 -5
- package/dist/types/passes-gate.d.ts.map +1 -1
- package/dist/types/project-config.d.ts +8 -66
- package/dist/types/project-config.d.ts.map +1 -1
- package/dist/types/project-config.js +3 -2
- package/dist/types/project-config.js.map +1 -1
- package/dist/types/trace.d.ts +8 -10
- package/dist/types/trace.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/CONTEXT.md +3 -3
- package/src/__tests__/checker-extra.test.ts +37 -61
- package/src/__tests__/checker.test.ts +10 -115
- package/src/__tests__/effective-constraints.test.ts +18 -83
- package/src/__tests__/iron-laws.test.ts +71 -90
- package/src/__tests__/passes-gate-check.test.ts +2 -2
- package/src/__tests__/project-config-loader-extra.test.ts +22 -123
- package/src/__tests__/project-config-loader.test.ts +5 -33
- package/src/__tests__/public-exports.test.ts +31 -11
- package/src/__tests__/public-type-surface.test.ts +2 -13
- package/src/__tests__/public-value-surface.test.ts +1 -7
- package/src/__tests__/skip-semantics.test.ts +21 -37
- package/src/__tests__/trace-analyzer-extra.test.ts +14 -14
- package/src/__tests__/trace-analyzer.test.ts +21 -21
- package/src/__tests__/trace-collector.test.ts +22 -22
- package/src/__tests__/traces.test.ts +27 -28
- package/src/cli/commands/CONTEXT.md +12 -9
- package/src/cli/commands/__tests__/check-read-count.test.ts +4 -15
- package/src/cli/commands/__tests__/check-skip-output.test.ts +14 -14
- package/src/cli/commands/__tests__/check.test.ts +14 -31
- package/src/cli/commands/__tests__/constraints-report.test.ts +12 -80
- package/src/cli/commands/__tests__/constraints-retire.test.ts +42 -231
- package/src/cli/commands/__tests__/init-governance-io.test.ts +12 -58
- package/src/cli/commands/__tests__/init-ondisk.test.ts +12 -20
- package/src/cli/commands/__tests__/init.test.ts +0 -11
- package/src/cli/commands/__tests__/project-path-anchoring.test.ts +2 -2
- package/src/cli/commands/__tests__/registry.test.ts +39 -3
- package/src/cli/commands/__tests__/report-extra.test.ts +4 -4
- package/src/cli/commands/__tests__/report.test.ts +1 -1
- package/src/cli/commands/__tests__/scaffold.test.ts +4 -14
- package/src/cli/commands/__tests__/status-analysis-wiring.test.ts +3 -3
- package/src/cli/commands/__tests__/status-extra.test.ts +14 -14
- package/src/cli/commands/__tests__/status.test.ts +12 -12
- package/src/cli/commands/__tests__/sync-docs-agents.test.ts +1 -1
- package/src/cli/commands/__tests__/sync-docs-table-layout.test.ts +259 -0
- package/src/cli/commands/check.ts +43 -82
- package/src/cli/commands/constraints-report.ts +4 -59
- package/src/cli/commands/constraints-retire.ts +49 -154
- package/src/cli/commands/constraints.ts +11 -26
- package/src/cli/commands/definitions.ts +2 -2
- package/src/cli/commands/init.ts +8 -179
- package/src/cli/commands/report.ts +19 -23
- package/src/cli/commands/scaffold-templates.ts +1 -37
- package/src/cli/commands/scaffold.ts +0 -11
- package/src/cli/commands/status.ts +10 -10
- package/src/cli/commands/sync-docs/agents-syncer.ts +4 -25
- package/src/cli/commands/sync-docs/capabilities-syncer.ts +139 -9
- package/src/cli/commands/sync-docs/index.ts +41 -4
- package/src/core/CONTEXT.md +9 -9
- package/src/core/constraints/__tests__/capability-counts.test.ts +5 -5
- package/src/core/constraints/__tests__/collect-constraints.test.ts +13 -8
- package/src/core/constraints/__tests__/git-evidence.test.ts +4 -7
- package/src/core/constraints/__tests__/injection-writer.test.ts +8 -61
- package/src/core/constraints/__tests__/run-env.test.ts +5 -34
- package/src/core/constraints/__tests__/trace-injection.test.ts +1 -1
- package/src/core/constraints/capabilities-parser.ts +17 -5
- package/src/core/constraints/checker.ts +39 -88
- package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +5 -8
- package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +1 -53
- package/src/core/constraints/checkers/__tests__/iron-flags.test.ts +5 -25
- package/src/core/constraints/checkers/docs-freshness.ts +1 -1
- package/src/core/constraints/checkers/governance-presence.ts +4 -3
- package/src/core/constraints/checkers/index.ts +4 -10
- package/src/core/constraints/checkers/iron-flags.ts +3 -12
- package/src/core/constraints/checkers/no-test-simplification.ts +1 -1
- package/src/core/constraints/checkers/types.ts +1 -1
- package/src/core/constraints/definitions/guidelines.ts +8 -25
- package/src/core/constraints/definitions/iron-laws.ts +9 -82
- package/src/core/constraints/definitions.ts +14 -15
- package/src/core/constraints/index.ts +4 -19
- package/src/core/constraints/injection-writer.ts +16 -61
- package/src/core/constraints/run-env.ts +1 -33
- package/src/core/constraints/usage-report.ts +8 -15
- package/src/core/effective-constraints.ts +14 -45
- package/src/core/index.ts +3 -10
- package/src/core/project-config-loader.ts +20 -145
- package/src/core/validators/passes-gate.ts +6 -6
- package/src/failure/CONTEXT.md +1 -1
- package/src/hooks/CONTEXT.md +12 -22
- package/src/hooks/__tests__/bootstrap.test.ts +24 -75
- package/src/hooks/bootstrap.ts +9 -48
- package/src/hooks/index.ts +5 -20
- package/src/index.ts +9 -31
- package/src/monitoring/__tests__/trace-file-anchoring.test.ts +1 -1
- package/src/monitoring/__tests__/traces.test.ts +22 -22
- package/src/monitoring/trace-analyzer.ts +12 -13
- package/src/monitoring/traces.ts +8 -8
- package/src/presets/__tests__/standard.test.ts +12 -16
- package/src/presets/standard.ts +14 -23
- package/src/types/__tests__/types.test.ts +3 -3
- package/src/types/constraint.ts +26 -40
- package/src/types/passes-gate.ts +5 -5
- package/src/types/project-config.ts +8 -77
- package/src/types/trace.ts +8 -11
- package/dist/core/constraints/agent-prompt-renderer.d.ts +0 -32
- package/dist/core/constraints/agent-prompt-renderer.d.ts.map +0 -1
- package/dist/core/constraints/agent-prompt-renderer.js +0 -55
- package/dist/core/constraints/agent-prompt-renderer.js.map +0 -1
- package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts +0 -6
- package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts.map +0 -1
- package/dist/core/constraints/checkers/no-bypass-checkpoint.js +0 -40
- package/dist/core/constraints/checkers/no-bypass-checkpoint.js.map +0 -1
- package/dist/core/constraints/definitions/prompts.d.ts +0 -12
- package/dist/core/constraints/definitions/prompts.d.ts.map +0 -1
- package/dist/core/constraints/definitions/prompts.js +0 -400
- package/dist/core/constraints/definitions/prompts.js.map +0 -1
- package/dist/core/constraints/injection-drift.d.ts +0 -61
- package/dist/core/constraints/injection-drift.d.ts.map +0 -1
- package/dist/core/constraints/injection-drift.js +0 -131
- package/dist/core/constraints/injection-drift.js.map +0 -1
- package/dist/core/constraints/injection-renderer.d.ts +0 -23
- package/dist/core/constraints/injection-renderer.d.ts.map +0 -1
- package/dist/core/constraints/injection-renderer.js +0 -44
- package/dist/core/constraints/injection-renderer.js.map +0 -1
- package/dist/hooks/config.d.ts +0 -30
- package/dist/hooks/config.d.ts.map +0 -1
- package/dist/hooks/config.js +0 -34
- package/dist/hooks/config.js.map +0 -1
- package/dist/hooks/pipeline.d.ts +0 -54
- package/dist/hooks/pipeline.d.ts.map +0 -1
- package/dist/hooks/pipeline.js +0 -173
- package/dist/hooks/pipeline.js.map +0 -1
- package/dist/hooks/registry.d.ts +0 -70
- package/dist/hooks/registry.d.ts.map +0 -1
- package/dist/hooks/registry.js +0 -141
- package/dist/hooks/registry.js.map +0 -1
- package/dist/hooks/types.d.ts +0 -113
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/hooks/types.js +0 -9
- package/dist/hooks/types.js.map +0 -1
- package/src/__tests__/hooks-pipeline.test.ts +0 -201
- package/src/cli/commands/__tests__/check-drift.test.ts +0 -158
- package/src/cli/commands/__tests__/init-injection.test.ts +0 -466
- package/src/core/constraints/__tests__/agent-prompt-renderer.test.ts +0 -129
- package/src/core/constraints/__tests__/injection-drift.test.ts +0 -247
- package/src/core/constraints/agent-prompt-renderer.ts +0 -67
- package/src/core/constraints/checkers/__tests__/no-bypass-checkpoint.test.ts +0 -76
- package/src/core/constraints/checkers/no-bypass-checkpoint.ts +0 -40
- package/src/core/constraints/definitions/prompts.ts +0 -414
- package/src/core/constraints/injection-drift.ts +0 -142
- package/src/core/constraints/injection-renderer.ts +0 -44
- package/src/hooks/__tests__/config.test.ts +0 -19
- package/src/hooks/__tests__/pipeline.test.ts +0 -195
- package/src/hooks/__tests__/registry.test.ts +0 -115
- package/src/hooks/config.ts +0 -33
- package/src/hooks/pipeline.ts +0 -202
- package/src/hooks/registry.ts +0 -166
- package/src/hooks/types.ts +0 -120
package/src/cli/commands/init.ts
CHANGED
|
@@ -10,21 +10,9 @@ import * as path from 'path';
|
|
|
10
10
|
import * as yaml from 'js-yaml';
|
|
11
11
|
import { detectSourceRoots } from '../../utils/detect-source-roots';
|
|
12
12
|
import { getHarnessPackageVersion } from '../../utils/package-version';
|
|
13
|
-
import { getEffectiveConstraints } from '../../core/effective-constraints';
|
|
14
13
|
import { loadRawProjectConfig } from '../../core/project-config-loader';
|
|
15
14
|
import type { CiConfig, CiPlatform, GovernanceConfig } from '../../types/project-config';
|
|
16
|
-
import {
|
|
17
|
-
CONSTRAINTS_START_MARKER,
|
|
18
|
-
CONSTRAINTS_END_MARKER,
|
|
19
|
-
renderConstraintsSection,
|
|
20
|
-
} from '../../core/constraints/injection-renderer';
|
|
21
|
-
import {
|
|
22
|
-
replaceStandaloneRange,
|
|
23
|
-
replaceEnclosedRange,
|
|
24
|
-
cutMarkerBlock,
|
|
25
|
-
resolveGovernanceLanding,
|
|
26
|
-
GOVERNANCE_HEADING,
|
|
27
|
-
} from '../../core/constraints/injection-writer';
|
|
15
|
+
import { replaceStandaloneRange } from '../../core/constraints/injection-writer';
|
|
28
16
|
import { log, logError, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
29
17
|
import {
|
|
30
18
|
runPlan,
|
|
@@ -32,7 +20,6 @@ import {
|
|
|
32
20
|
preCommitHookFile,
|
|
33
21
|
prePushHookFile,
|
|
34
22
|
harnessCheckCiFile,
|
|
35
|
-
customConstraintsFile,
|
|
36
23
|
changelogFile,
|
|
37
24
|
contextDocFile,
|
|
38
25
|
governanceWorkflowFile,
|
|
@@ -294,9 +281,9 @@ export async function init(options: InitOptions, io: CommandIO = processIO): Pro
|
|
|
294
281
|
await fs.writeFile(configPath, configContent, 'utf-8');
|
|
295
282
|
log(io, chalk.green(`✅ 已创建配置文件: ${configPath} (v${pkgVersion})`));
|
|
296
283
|
|
|
297
|
-
// 受管示例文件:检查点 / Resolutions(RKB
|
|
284
|
+
// 受管示例文件:检查点 / Resolutions(RKB 狗粮)
|
|
298
285
|
await runPlan(
|
|
299
|
-
[checkpointsFile(projectPath), resolutionsFile(projectPath)
|
|
286
|
+
[checkpointsFile(projectPath), resolutionsFile(projectPath)],
|
|
300
287
|
io,
|
|
301
288
|
);
|
|
302
289
|
|
|
@@ -322,9 +309,8 @@ export async function init(options: InitOptions, io: CommandIO = processIO): Pro
|
|
|
322
309
|
log(io);
|
|
323
310
|
log(io, chalk.gray('下一步:'));
|
|
324
311
|
log(io, chalk.gray(' 1. 编辑 .harness/config.yml 自定义配置'));
|
|
325
|
-
log(io, chalk.gray(' 2.
|
|
326
|
-
log(io, chalk.gray(' 3.
|
|
327
|
-
log(io, chalk.gray(' 4. 运行 harness status 查看状态'));
|
|
312
|
+
log(io, chalk.gray(' 2. 正常开发:每次 git commit 查暂存的(增量快反馈),每次 git push 查整仓的(全量兜底)——重复是设计使然'));
|
|
313
|
+
log(io, chalk.gray(' 3. 运行 harness status 查看状态'));
|
|
328
314
|
log(io);
|
|
329
315
|
log(io, chalk.blue('💡 提示: 使用 harness init --print-snippets 查看配置代码片段'));
|
|
330
316
|
return { kind: 'ok' };
|
|
@@ -463,7 +449,7 @@ export async function setupClaudeMdOutputStyle(projectPath: string, io: CommandI
|
|
|
463
449
|
try {
|
|
464
450
|
content = await fs.readFile(claudeMdPath, 'utf-8');
|
|
465
451
|
} catch {
|
|
466
|
-
// CLAUDE.md
|
|
452
|
+
// CLAUDE.md 不存在——无人持有该文件,跳过 Output Style 段
|
|
467
453
|
return;
|
|
468
454
|
}
|
|
469
455
|
|
|
@@ -512,159 +498,6 @@ export async function setupClaudeMdOutputStyle(projectPath: string, io: CommandI
|
|
|
512
498
|
log(io, chalk.green('✅ 已在 CLAUDE.md 顶部写入 Output Style 段'));
|
|
513
499
|
}
|
|
514
500
|
|
|
515
|
-
/**
|
|
516
|
-
* 治理契约 PRESERVE 段标记(studio #302,ADR 2026-08-21 落点模型:
|
|
517
|
-
* 治理契约正本住 AGENTS.md 手写 PRESERVE 段,sync-docs 重新生成时原样保留)
|
|
518
|
-
*/
|
|
519
|
-
const GOVERNANCE_PRESERVE_BEGIN = '<!-- PRESERVE:governance -->';
|
|
520
|
-
const GOVERNANCE_PRESERVE_END = '<!-- /PRESERVE:governance -->';
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* 在 AGENTS.md 的 PRESERVE:governance 段写入/更新 Governance Rules 约束段(新落点模型)
|
|
524
|
-
*
|
|
525
|
-
* - AGENTS.md 不存在:创建最小骨架(标题 + 说明 + PRESERVE:governance 段),
|
|
526
|
-
* 完整导读由 `harness sync-docs --agents` 生成,PRESERVE 段在重新生成时原样保留
|
|
527
|
-
* - 已有 PRESERVE:governance 段:段内机器管理的只有 HARNESS_CONSTRAINTS 标记区间——
|
|
528
|
-
* 有标记则只替换标记区间,段内其余手写内容(治理契约引言/流程/纪律等)原样保留;
|
|
529
|
-
* 无标记(纯手写段)则在段尾追加注入段,不动手写内容
|
|
530
|
-
* - 无该段:在文件末尾追加
|
|
531
|
-
* - 段标记残缺(外层或段内 HARNESS_CONSTRAINTS 单边/乱序):不写入,告警交由人工修复(防二次损坏)
|
|
532
|
-
*/
|
|
533
|
-
export async function setupAgentsMdConstraints(projectPath: string, io: CommandIO): Promise<void> {
|
|
534
|
-
const agentsMdPath = path.join(projectPath, 'AGENTS.md');
|
|
535
|
-
const version = getHarnessPackageVersion();
|
|
536
|
-
|
|
537
|
-
const constraints = getEffectiveConstraints(projectPath);
|
|
538
|
-
const bodyOnly = renderConstraintsSection(constraints, version);
|
|
539
|
-
const block = `${GOVERNANCE_PRESERVE_BEGIN}\n${GOVERNANCE_HEADING}\n${bodyOnly}${GOVERNANCE_PRESERVE_END}\n`;
|
|
540
|
-
|
|
541
|
-
let existingContent: string | null = null;
|
|
542
|
-
try {
|
|
543
|
-
existingContent = await fs.readFile(agentsMdPath, 'utf-8');
|
|
544
|
-
} catch {
|
|
545
|
-
// AGENTS.md 不存在
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (existingContent === null) {
|
|
549
|
-
const skeleton = [
|
|
550
|
-
'# AGENTS.md',
|
|
551
|
-
'',
|
|
552
|
-
'> 机器生成部分由 `harness sync-docs --agents` 维护;`PRESERVE:governance` 段是治理契约正本(手写/治理变更流程管控),重新生成时原样保留。',
|
|
553
|
-
'',
|
|
554
|
-
block,
|
|
555
|
-
].join('\n');
|
|
556
|
-
await fs.writeFile(agentsMdPath, skeleton, 'utf-8');
|
|
557
|
-
log(io, chalk.green(`✅ 已创建 AGENTS.md 并写入治理契约 PRESERVE:governance 段 (v${version})`));
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
const preserve = cutMarkerBlock(existingContent, GOVERNANCE_PRESERVE_BEGIN, GOVERNANCE_PRESERVE_END);
|
|
562
|
-
|
|
563
|
-
if (preserve === 'half') {
|
|
564
|
-
log(io, chalk.yellow('⚠️ AGENTS.md 中 PRESERVE:governance 标记残缺(只有单边),跳过治理契约写入,请人工修复'));
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
if (preserve !== 'absent') {
|
|
569
|
-
// 段内机器管理的只有 HARNESS_CONSTRAINTS 标记区间;其余手写内容原样保留
|
|
570
|
-
const inner = replaceEnclosedRange(preserve.inner, CONSTRAINTS_START_MARKER, CONSTRAINTS_END_MARKER, bodyOnly);
|
|
571
|
-
if (inner.kind === 'half') {
|
|
572
|
-
log(io, chalk.yellow('⚠️ AGENTS.md PRESERVE:governance 段内 HARNESS_CONSTRAINTS 标记残缺(单边或乱序),跳过治理契约写入,请人工修复'));
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
const newInner =
|
|
576
|
-
inner.kind === 'updated'
|
|
577
|
-
? inner.content
|
|
578
|
-
: // 纯手写段(无约束标记):段尾追加注入段,手写内容不动
|
|
579
|
-
preserve.inner.trimEnd() + '\n\n' + GOVERNANCE_HEADING + '\n' + bodyOnly;
|
|
580
|
-
|
|
581
|
-
const write = replaceStandaloneRange(
|
|
582
|
-
existingContent,
|
|
583
|
-
GOVERNANCE_PRESERVE_BEGIN,
|
|
584
|
-
GOVERNANCE_PRESERVE_END,
|
|
585
|
-
GOVERNANCE_PRESERVE_BEGIN + newInner + GOVERNANCE_PRESERVE_END + '\n'
|
|
586
|
-
);
|
|
587
|
-
if (write.kind === 'updated' && write.content !== existingContent) {
|
|
588
|
-
await fs.writeFile(agentsMdPath, write.content, 'utf-8');
|
|
589
|
-
log(io, chalk.green(`✅ 已更新 AGENTS.md 治理契约 PRESERVE:governance 段 (v${version})`));
|
|
590
|
-
}
|
|
591
|
-
return;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// 无该段:文件末尾追加
|
|
595
|
-
const newContent = existingContent.trimEnd() + '\n\n' + block;
|
|
596
|
-
await fs.writeFile(agentsMdPath, newContent, 'utf-8');
|
|
597
|
-
log(io, chalk.green(`✅ 已追加治理契约 PRESERVE:governance 段到 AGENTS.md (v${version})`));
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
/**
|
|
601
|
-
* 在 CLAUDE.md 中写入/更新 Governance Rules 约束段(旧落点模型,向后兼容保留)
|
|
602
|
-
*
|
|
603
|
-
* - 约束集来自 getEffectiveConstraints(ADR-0001):preset 裁剪、config.yml
|
|
604
|
-
* 禁用、custom 追加、scenes 过滤全部反映在注入文本里
|
|
605
|
-
* - 期望段文本由纯函数 renderConstraintsSection 渲染(P6 漂移校验复用)
|
|
606
|
-
* - 如果 CLAUDE.md 不存在,创建并写入完整约束段
|
|
607
|
-
* - 如果存在 HARNESS_CONSTRAINTS_START/END 标记,替换标记间内容
|
|
608
|
-
* - 如果不存在标记,在文件末尾追加约束段
|
|
609
|
-
*/
|
|
610
|
-
export async function setupClaudeMdConstraints(projectPath: string, io: CommandIO): Promise<void> {
|
|
611
|
-
const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
|
|
612
|
-
|
|
613
|
-
const version = getHarnessPackageVersion();
|
|
614
|
-
|
|
615
|
-
// 生效约束集 → 渲染期望段(纯函数,与写文件分离)
|
|
616
|
-
const constraints = getEffectiveConstraints(projectPath);
|
|
617
|
-
const bodyOnly = renderConstraintsSection(constraints, version);
|
|
618
|
-
const fullSection = GOVERNANCE_HEADING + '\n' + bodyOnly;
|
|
619
|
-
|
|
620
|
-
// 检查 CLAUDE.md 是否存在
|
|
621
|
-
let existingContent: string;
|
|
622
|
-
let fileExists = false;
|
|
623
|
-
try {
|
|
624
|
-
existingContent = await fs.readFile(claudeMdPath, 'utf-8');
|
|
625
|
-
fileExists = true;
|
|
626
|
-
} catch {
|
|
627
|
-
existingContent = '';
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
if (!fileExists) {
|
|
631
|
-
// 创建新文件
|
|
632
|
-
await fs.writeFile(claudeMdPath, fullSection, 'utf-8');
|
|
633
|
-
log(io, chalk.green(`✅ 已创建 CLAUDE.md 并写入治理约束 (v${version})`));
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
const write = replaceStandaloneRange(existingContent, CONSTRAINTS_START_MARKER, CONSTRAINTS_END_MARKER, bodyOnly);
|
|
638
|
-
|
|
639
|
-
if (write.kind === 'updated') {
|
|
640
|
-
// 替换标记区间含标记本身(保持包括最新版本号),尾部换行规范化在 writer 内
|
|
641
|
-
await fs.writeFile(claudeMdPath, write.content, 'utf-8');
|
|
642
|
-
log(io, chalk.green(`✅ 已更新 CLAUDE.md 治理约束 (v${version})`));
|
|
643
|
-
} else if (write.kind === 'half') {
|
|
644
|
-
log(io, chalk.yellow('⚠️ CLAUDE.md 中 HARNESS_CONSTRAINTS 标记残缺(单边或乱序),跳过治理约束注入,请人工修复'));
|
|
645
|
-
} else {
|
|
646
|
-
// 在文件末尾追加完整段
|
|
647
|
-
const newContent = existingContent.trimEnd() + '\n\n' + fullSection;
|
|
648
|
-
await fs.writeFile(claudeMdPath, newContent, 'utf-8');
|
|
649
|
-
log(io, chalk.green(`✅ 已追加治理约束到 CLAUDE.md (v${version})`));
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* 治理约束段写入落点路由(studio #302,ADR 2026-08-21 落点模型)
|
|
655
|
-
*
|
|
656
|
-
* 判定收口在 core/constraints/injection-writer resolveGovernanceLanding:
|
|
657
|
-
* - 旧模型仓(CLAUDE.md 已有 HARNESS_CONSTRAINTS 标记或 `## Governance Rules` 块):
|
|
658
|
-
* 继续写 CLAUDE.md——init 幂等重跑不破坏既有仓,不制造双份约束正本
|
|
659
|
-
* - 其余(新仓初始化):写 AGENTS.md PRESERVE:governance 段(入库公共面正本)
|
|
660
|
-
*/
|
|
661
|
-
export async function setupGovernanceConstraints(projectPath: string, io: CommandIO): Promise<void> {
|
|
662
|
-
const { target } = resolveGovernanceLanding(projectPath);
|
|
663
|
-
return target === 'claude-md'
|
|
664
|
-
? setupClaudeMdConstraints(projectPath, io)
|
|
665
|
-
: setupAgentsMdConstraints(projectPath, io);
|
|
666
|
-
}
|
|
667
|
-
|
|
668
501
|
/**
|
|
669
502
|
* 设置治理相关文件
|
|
670
503
|
*/
|
|
@@ -686,14 +519,10 @@ async function setupGovernance(
|
|
|
686
519
|
// 2. 在 CLAUDE.md 中写入 Output Style 段(仅在不存在时创建)
|
|
687
520
|
await setupClaudeMdOutputStyle(projectPath, io);
|
|
688
521
|
|
|
689
|
-
// 3.
|
|
690
|
-
// 旧模型仓 → CLAUDE.md,落点路由见 setupGovernanceConstraints)
|
|
691
|
-
await setupGovernanceConstraints(projectPath, io);
|
|
692
|
-
|
|
693
|
-
// 4. 生成 CONTEXT.md 文件(预设形状即 GovernanceConfig,无需再 cast)
|
|
522
|
+
// 3. 生成 CONTEXT.md 文件(预设形状即 GovernanceConfig,无需再 cast)
|
|
694
523
|
await runPlan(await contextDocPlan(projectPath, governance, io), io);
|
|
695
524
|
|
|
696
|
-
//
|
|
525
|
+
// 4. 生成治理 CI 面(仅 github 形;gitlab 已并入 .gitlab-ci.yml 正文,none 不建,harness#156)
|
|
697
526
|
await setupGovernanceWorkflow(projectPath, level, io, platform);
|
|
698
527
|
}
|
|
699
528
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import * as fs from 'fs/promises';
|
|
9
9
|
import { ConstraintChecker } from '../../core/constraints/checker';
|
|
10
|
-
import {
|
|
10
|
+
import { CONSTRAINTS } from '../../core/constraints/definitions';
|
|
11
11
|
import { TraceCollector } from '../../monitoring/traces';
|
|
12
12
|
import type { ConstraintContext } from '../../types/constraint';
|
|
13
13
|
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
@@ -26,15 +26,14 @@ interface ReportData {
|
|
|
26
26
|
projectPath: string;
|
|
27
27
|
constraints: {
|
|
28
28
|
total: number;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
prompts: number;
|
|
29
|
+
errors: number;
|
|
30
|
+
warnings: number;
|
|
32
31
|
passed: number;
|
|
33
32
|
failed: number;
|
|
34
|
-
|
|
33
|
+
warningViolations: number;
|
|
35
34
|
violations: Array<{
|
|
36
35
|
id: string;
|
|
37
|
-
|
|
36
|
+
severity: string;
|
|
38
37
|
message: string;
|
|
39
38
|
}>;
|
|
40
39
|
};
|
|
@@ -51,23 +50,22 @@ export async function report(options: ReportOptions, io: CommandIO = processIO):
|
|
|
51
50
|
// #139:收集器锚根构造——不传 projectPath 时 trace 会落进调用方 cwd,B 侧读不到
|
|
52
51
|
const checker = new ConstraintChecker(new TraceCollector({ projectPath }));
|
|
53
52
|
|
|
54
|
-
const
|
|
55
|
-
const totalConstraints = Object.keys(allConstraints).length;
|
|
53
|
+
const totalConstraints = Object.keys(CONSTRAINTS).length;
|
|
56
54
|
|
|
57
55
|
const context: ConstraintContext = {
|
|
58
56
|
operation: 'file_modification',
|
|
59
57
|
projectPath,
|
|
60
58
|
};
|
|
61
59
|
|
|
62
|
-
// 收集模式(架构评审候选1
|
|
60
|
+
// 收集模式(架构评审候选1):不抛、全量收集,error 级违规如实进报告
|
|
63
61
|
const result = await checker.collectConstraints(context);
|
|
64
62
|
|
|
65
|
-
const
|
|
66
|
-
const
|
|
63
|
+
const failedErrors = result.errors.filter(r => !r.satisfied);
|
|
64
|
+
const failedWarnings = result.warnings.filter(r => !r.satisfied);
|
|
67
65
|
|
|
68
|
-
const violations = [...
|
|
66
|
+
const violations = [...failedErrors, ...failedWarnings].map(r => ({
|
|
69
67
|
id: r.id,
|
|
70
|
-
|
|
68
|
+
severity: r.severity,
|
|
71
69
|
message: r.message || '',
|
|
72
70
|
}));
|
|
73
71
|
|
|
@@ -76,12 +74,11 @@ export async function report(options: ReportOptions, io: CommandIO = processIO):
|
|
|
76
74
|
projectPath,
|
|
77
75
|
constraints: {
|
|
78
76
|
total: totalConstraints,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
prompts: Object.keys(PROMPTS).length,
|
|
77
|
+
errors: Object.values(CONSTRAINTS).filter(c => c.severity === 'error').length,
|
|
78
|
+
warnings: Object.values(CONSTRAINTS).filter(c => c.severity === 'warning').length,
|
|
82
79
|
passed: result.passed ? totalConstraints : totalConstraints - violations.length,
|
|
83
|
-
failed:
|
|
84
|
-
|
|
80
|
+
failed: failedErrors.length,
|
|
81
|
+
warningViolations: failedWarnings.length,
|
|
85
82
|
violations,
|
|
86
83
|
},
|
|
87
84
|
};
|
|
@@ -122,19 +119,18 @@ function generateMarkdownReport(data: ReportData): string {
|
|
|
122
119
|
`| 指标 | 数值 |`,
|
|
123
120
|
`|------|------|`,
|
|
124
121
|
`| 总约束 | ${data.constraints.total} |`,
|
|
125
|
-
`|
|
|
126
|
-
`|
|
|
127
|
-
`| Prompts | ${data.constraints.prompts} |`,
|
|
122
|
+
`| error 级 | ${data.constraints.errors} |`,
|
|
123
|
+
`| warning 级 | ${data.constraints.warnings} |`,
|
|
128
124
|
`| 通过 | ${data.constraints.passed} |`,
|
|
129
125
|
`| 失败 (error) | ${data.constraints.failed} |`,
|
|
130
|
-
`| 警告 (warning) | ${data.constraints.
|
|
126
|
+
`| 警告 (warning) | ${data.constraints.warningViolations} |`,
|
|
131
127
|
``,
|
|
132
128
|
];
|
|
133
129
|
|
|
134
130
|
if (data.constraints.violations.length > 0) {
|
|
135
131
|
lines.push(`### 违规项`, ``);
|
|
136
132
|
data.constraints.violations.forEach(v => {
|
|
137
|
-
lines.push(`- **${v.id}** (${v.
|
|
133
|
+
lines.push(`- **${v.id}** (${v.severity}): ${v.message}`);
|
|
138
134
|
});
|
|
139
135
|
lines.push(``);
|
|
140
136
|
}
|
|
@@ -249,42 +249,6 @@ ${docsCheckStep}
|
|
|
249
249
|
`;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
/** custom-constraints.yml 示例正文 */
|
|
253
|
-
export const CUSTOM_CONSTRAINTS_TEMPLATE = `# 自定义约束配置
|
|
254
|
-
#
|
|
255
|
-
# 此文件定义项目特定的约束,扩展或覆盖 harness 内置约束
|
|
256
|
-
|
|
257
|
-
# ========================================
|
|
258
|
-
# 自定义约束示例
|
|
259
|
-
# ========================================
|
|
260
|
-
|
|
261
|
-
custom_constraints:
|
|
262
|
-
# 示例 1:禁止 console.log
|
|
263
|
-
# my_project_no_console_log:
|
|
264
|
-
# id: my_project_no_console_log
|
|
265
|
-
# level: guideline
|
|
266
|
-
# rule: "NO CONSOLE.LOG IN PRODUCTION CODE"
|
|
267
|
-
# message: "生产代码禁止使用 console.log,请使用 logger 模块"
|
|
268
|
-
# trigger: ["code_implementation"]
|
|
269
|
-
# description: "使用项目统一的 logger 模块代替 console.log"
|
|
270
|
-
|
|
271
|
-
# 示例 2:禁止特定的导入
|
|
272
|
-
# my_project_no_moment_js:
|
|
273
|
-
# id: my_project_no_moment_js
|
|
274
|
-
# level: guideline
|
|
275
|
-
# rule: "NO MOMENT.JS IMPORTS"
|
|
276
|
-
# message: "禁止使用 moment.js,请使用 date-fns 或 dayjs"
|
|
277
|
-
# trigger: ["code_implementation"]
|
|
278
|
-
|
|
279
|
-
# 示例 3:要求特定的文件命名
|
|
280
|
-
# my_project_component_naming:
|
|
281
|
-
# id: my_project_component_naming
|
|
282
|
-
# level: tip
|
|
283
|
-
# rule: "REACT COMPONENTS SHOULD BE PASCAL CASE"
|
|
284
|
-
# message: "React 组件文件名应使用 PascalCase"
|
|
285
|
-
# trigger: ["file_creation"]
|
|
286
|
-
`;
|
|
287
|
-
|
|
288
252
|
/** CHANGELOG.md 正文(`format` 来自治理配置的 changelog.format) */
|
|
289
253
|
export function renderChangelog(format: string): string {
|
|
290
254
|
return format === 'keep-a-changelog'
|
|
@@ -386,7 +350,7 @@ export function renderCheckpoints(): string {
|
|
|
386
350
|
|
|
387
351
|
/** 默认 Resolutions(RKB — 约束 → 已知解法映射) */
|
|
388
352
|
const DEFAULT_RESOLUTIONS = {
|
|
389
|
-
|
|
353
|
+
no_completion_without_verification: {
|
|
390
354
|
title: 'commit message 缺少验证证据',
|
|
391
355
|
fix: '在 commit message body 中附上验证输出:\n`npx @dommaker/harness check --staged` | `npx @dommaker/harness validate` | `npm test -- --coverage`\n确认全部通过后重新 commit。',
|
|
392
356
|
},
|
|
@@ -20,7 +20,6 @@ import * as nodeFs from 'fs/promises';
|
|
|
20
20
|
import type { CiPlatform } from '../../types/project-config';
|
|
21
21
|
import { log, type CommandIO } from '../command-contract';
|
|
22
22
|
import {
|
|
23
|
-
CUSTOM_CONSTRAINTS_TEMPLATE,
|
|
24
23
|
DEFAULT_CHECKPOINT_FILE,
|
|
25
24
|
HARNESS_CHECK_WORKFLOW,
|
|
26
25
|
PRE_COMMIT_SNIPPET,
|
|
@@ -235,16 +234,6 @@ export function harnessCheckCiFile(
|
|
|
235
234
|
};
|
|
236
235
|
}
|
|
237
236
|
|
|
238
|
-
/** .harness/custom-constraints.yml 示例 */
|
|
239
|
-
export function customConstraintsFile(projectPath: string): ManagedFile {
|
|
240
|
-
return {
|
|
241
|
-
target: path.join(projectPath, '.harness', 'custom-constraints.yml'),
|
|
242
|
-
content: CUSTOM_CONSTRAINTS_TEMPLATE,
|
|
243
|
-
created: '✅ 已创建自定义约束示例: custom-constraints.yml',
|
|
244
|
-
onPresent: { outcome: 'skip', notice: 'custom-constraints.yml 已存在' },
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
237
|
/** .harness/checkpoints.yml 示例(原住 validate.ts,路径约定与 validate 共用) */
|
|
249
238
|
export function checkpointsFile(projectPath: string): ManagedFile {
|
|
250
239
|
const target = path.join(projectPath, DEFAULT_CHECKPOINT_FILE);
|
|
@@ -109,11 +109,11 @@ export async function status(options: StatusOptions, io: CommandIO = processIO):
|
|
|
109
109
|
log(io, chalk.blue('📈 约束统计:'));
|
|
110
110
|
log(io);
|
|
111
111
|
|
|
112
|
-
//
|
|
113
|
-
const
|
|
114
|
-
if (
|
|
115
|
-
log(io, chalk.red('🔴
|
|
116
|
-
|
|
112
|
+
// severity='error'
|
|
113
|
+
const errorSummaries = summaries.filter((s: TraceSummary) => s.severity === 'error');
|
|
114
|
+
if (errorSummaries.length > 0) {
|
|
115
|
+
log(io, chalk.red('🔴 error 级约束:'));
|
|
116
|
+
errorSummaries.forEach((s: TraceSummary) => {
|
|
117
117
|
const status = s.passRate >= 1 ? '✅' : '❌';
|
|
118
118
|
log(io, ` ${status} ${s.constraintId}`);
|
|
119
119
|
if (options.detail) {
|
|
@@ -123,11 +123,11 @@ export async function status(options: StatusOptions, io: CommandIO = processIO):
|
|
|
123
123
|
log(io);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
//
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
log(io, chalk.yellow('🟡
|
|
130
|
-
|
|
126
|
+
// severity='warning'
|
|
127
|
+
const warningSummaries = summaries.filter((s: TraceSummary) => s.severity === 'warning');
|
|
128
|
+
if (warningSummaries.length > 0) {
|
|
129
|
+
log(io, chalk.yellow('🟡 warning 级约束:'));
|
|
130
|
+
warningSummaries.forEach((s: TraceSummary) => {
|
|
131
131
|
const status = s.passRate >= 0.8 ? '✅' : s.passRate >= 0.5 ? '⚠️' : '❌';
|
|
132
132
|
log(io, ` ${status} ${s.constraintId}`);
|
|
133
133
|
if (options.detail) {
|
|
@@ -49,8 +49,6 @@ export interface GovernanceInfo {
|
|
|
49
49
|
hasConfig: boolean;
|
|
50
50
|
preset?: string;
|
|
51
51
|
hasClaudeGovernance: boolean;
|
|
52
|
-
ironLaws?: number;
|
|
53
|
-
guidelines?: number;
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
/**
|
|
@@ -114,11 +112,7 @@ export async function buildAgentsMd(projectPath: string, srcDirs: string[]): Pro
|
|
|
114
112
|
lines.push(`- 治理配置:\`.harness/config.yml\`${governance.preset ? `(preset: ${governance.preset})` : ''}`);
|
|
115
113
|
}
|
|
116
114
|
if (governance.hasClaudeGovernance) {
|
|
117
|
-
|
|
118
|
-
governance.ironLaws !== undefined ? `Iron Laws ${governance.ironLaws} 条` : null,
|
|
119
|
-
governance.guidelines !== undefined ? `Guidelines ${governance.guidelines} 条` : null,
|
|
120
|
-
].filter(Boolean).join('、');
|
|
121
|
-
lines.push(`- 约束清单:\`CLAUDE.md\` Governance Rules 块${counts ? `(${counts})` : ''}`);
|
|
115
|
+
lines.push('- 约束清单:`CLAUDE.md` Governance Rules 块');
|
|
122
116
|
}
|
|
123
117
|
if (!governance.hasConfig && !governance.hasClaudeGovernance) {
|
|
124
118
|
lines.push('- 未检测到 harness 治理配置,可运行 `harness init` 初始化');
|
|
@@ -208,7 +202,7 @@ async function listWorkspaceMembers(dir: string): Promise<string[]> {
|
|
|
208
202
|
}
|
|
209
203
|
}
|
|
210
204
|
|
|
211
|
-
/** 收集治理信息:.harness/config.yml 与 CLAUDE.md
|
|
205
|
+
/** 收集治理信息:.harness/config.yml 与 CLAUDE.md 治理块 */
|
|
212
206
|
async function getGovernanceInfo(projectPath: string): Promise<GovernanceInfo> {
|
|
213
207
|
const info: GovernanceInfo = { hasConfig: false, hasClaudeGovernance: false };
|
|
214
208
|
|
|
@@ -224,12 +218,8 @@ async function getGovernanceInfo(projectPath: string): Promise<GovernanceInfo> {
|
|
|
224
218
|
|
|
225
219
|
try {
|
|
226
220
|
const claude = await fs.readFile(path.join(projectPath, 'CLAUDE.md'), 'utf-8');
|
|
227
|
-
// 契约在场判定收口 injection-writer.hasGovernanceContract(#83,与 presence
|
|
228
|
-
|
|
229
|
-
info.hasClaudeGovernance = true;
|
|
230
|
-
info.ironLaws = countConstraintBullets(claude, 'Iron Laws');
|
|
231
|
-
info.guidelines = countConstraintBullets(claude, 'Guidelines');
|
|
232
|
-
}
|
|
221
|
+
// 契约在场判定收口 injection-writer.hasGovernanceContract(#83,与 presence 同谓词)
|
|
222
|
+
info.hasClaudeGovernance = hasGovernanceContract(claude);
|
|
233
223
|
} catch {
|
|
234
224
|
// CLAUDE.md 不存在
|
|
235
225
|
}
|
|
@@ -237,17 +227,6 @@ async function getGovernanceInfo(projectPath: string): Promise<GovernanceInfo> {
|
|
|
237
227
|
return info;
|
|
238
228
|
}
|
|
239
229
|
|
|
240
|
-
/** 统计 CLAUDE.md 指定约束分节下的条目数(`- **key**:` 行),分节不存在时返回 undefined */
|
|
241
|
-
function countConstraintBullets(content: string, section: string): number | undefined {
|
|
242
|
-
const heading = new RegExp(`^###\\s+${section}[^\\n]*$`, 'm').exec(content);
|
|
243
|
-
if (!heading) return undefined;
|
|
244
|
-
const rest = content.slice(heading.index + heading[0].length);
|
|
245
|
-
const end = rest.search(/^###\s|^\s*<!--\s*HARNESS_CONSTRAINTS_END/m);
|
|
246
|
-
const block = end === -1 ? rest : rest.slice(0, end);
|
|
247
|
-
const items = block.match(/^-\s+\*\*[A-Za-z0-9_]+\*\*/gm);
|
|
248
|
-
return items ? items.length : 0;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
230
|
/** 判断 .harness/knowledge 目录是否存在(只判存在性,不统计条数——条数易变,见 buildAgentsMd 注释) */
|
|
252
231
|
async function hasKnowledgeDir(projectPath: string): Promise<boolean> {
|
|
253
232
|
try {
|