@dommaker/harness 1.9.0 → 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 +6 -0
- package/README.md +9 -12
- 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/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/index.d.ts +7 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -18
- 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 +2 -2
- 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 +1 -7
- package/src/__tests__/public-type-surface.test.ts +2 -5
- 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 +9 -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__/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/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/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/__tests__/bootstrap.test.ts +3 -5
- package/src/index.ts +8 -18
- 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/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
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* 治理约束注入段漂移校验(ADR-0001 决策 7)
|
|
4
|
-
*
|
|
5
|
-
* 检测三类漂移:
|
|
6
|
-
* 1. 版本漂移:标记段内 `<!-- version: x -->` ≠ 当前 harness 包版本
|
|
7
|
-
* 2. 内容漂移:标记段实际条目 ≠ renderConstraintsSection(当前生效集, 当前版本)
|
|
8
|
-
* (手改裁剪 / harness 升级后未重跑 init / config.yml 变更后未同步),
|
|
9
|
-
* 产出条目级差异(missing/extra),比逐行 diff 更可读
|
|
10
|
-
* 3. 重复章节:标记段之外还存在另一个 `## Governance Rules` 标题
|
|
11
|
-
* (init 旧版本在无标记时追加第二个同名章节的历史问题)
|
|
12
|
-
*
|
|
13
|
-
* 落点路由(studio #307,ADR 2026-08-21 落点模型):注入段可能在
|
|
14
|
-
* CLAUDE.md(旧模型仓)或 AGENTS.md `PRESERVE:governance` 段内(新模型仓),
|
|
15
|
-
* 与 init 的 setupGovernanceConstraints 路由一致——CLAUDE.md 有标记优先。
|
|
16
|
-
*
|
|
17
|
-
* 纯检测、只读:不改任何文件。check 仅警告不阻断,详细差异进 report。
|
|
18
|
-
* 两处均无标记段 = 未注入,不算漂移(report 一句话提示,check 不警告)。
|
|
19
|
-
*/
|
|
20
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
-
if (k2 === undefined) k2 = k;
|
|
22
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
-
}
|
|
26
|
-
Object.defineProperty(o, k2, desc);
|
|
27
|
-
}) : (function(o, m, k, k2) {
|
|
28
|
-
if (k2 === undefined) k2 = k;
|
|
29
|
-
o[k2] = m[k];
|
|
30
|
-
}));
|
|
31
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
-
}) : function(o, v) {
|
|
34
|
-
o["default"] = v;
|
|
35
|
-
});
|
|
36
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
-
var ownKeys = function(o) {
|
|
38
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
-
var ar = [];
|
|
40
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
-
return ar;
|
|
42
|
-
};
|
|
43
|
-
return ownKeys(o);
|
|
44
|
-
};
|
|
45
|
-
return function (mod) {
|
|
46
|
-
if (mod && mod.__esModule) return mod;
|
|
47
|
-
var result = {};
|
|
48
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
-
__setModuleDefault(result, mod);
|
|
50
|
-
return result;
|
|
51
|
-
};
|
|
52
|
-
})();
|
|
53
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
-
exports.INJECTION_DRIFT_FIX_HINT = void 0;
|
|
55
|
-
exports.detectInjectionDrift = detectInjectionDrift;
|
|
56
|
-
const path = __importStar(require("path"));
|
|
57
|
-
const effective_constraints_1 = require("../effective-constraints");
|
|
58
|
-
const run_env_1 = require("./run-env");
|
|
59
|
-
const package_version_1 = require("../../utils/package-version");
|
|
60
|
-
const injection_renderer_1 = require("./injection-renderer");
|
|
61
|
-
const injection_writer_1 = require("./injection-writer");
|
|
62
|
-
/** 修复指引(重跑 init 幂等同步注入段) */
|
|
63
|
-
exports.INJECTION_DRIFT_FIX_HINT = '重跑 `npx @dommaker/harness init` 同步注入段(漂移仅警告,不阻断)';
|
|
64
|
-
const VERSION_LINE_RE = /<!-- version: ([^ ]+) -->/;
|
|
65
|
-
const ENTRY_LINE_RE = /^- \*\*.+?\*\*: .+$/;
|
|
66
|
-
const GROUP_HEADING_RE = /^### .+$/;
|
|
67
|
-
/**
|
|
68
|
-
* 提取参与条目级比对的"有效行":注入条目(- **id**: text)与分组标题(### ...)。
|
|
69
|
-
* 标记行、版本行、空行不参与——版本单独比对,空行/标记属排版噪音。
|
|
70
|
-
*/
|
|
71
|
-
function significantLines(section) {
|
|
72
|
-
return section
|
|
73
|
-
.split('\n')
|
|
74
|
-
.map(l => l.trim())
|
|
75
|
-
.filter(l => ENTRY_LINE_RE.test(l) || GROUP_HEADING_RE.test(l));
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 检测约束注入段漂移
|
|
79
|
-
*
|
|
80
|
-
* @param target 项目根路径,或本 run 的运行级观察面(CLI check 传入即与本 run 共用
|
|
81
|
-
* 同一份 config.yml 读取,漂移侧的生效集计算不再重读文件——ADR-0023 决策 2)
|
|
82
|
-
* @param currentVersion 当前 harness 版本(缺省经 getHarnessPackageVersion 正本读取;测试可显式传入)
|
|
83
|
-
* @param expectedConstraints 本 run 已算好的生效集(CLI check 传入 → 生效集链路一次运行只算
|
|
84
|
-
* 一遍,且比对用的就是本 run 实际执法的那份)。不传则按 target 自取,行为与改前逐字一致
|
|
85
|
-
*/
|
|
86
|
-
function detectInjectionDrift(target, currentVersion = (0, package_version_1.getHarnessPackageVersion)(), expectedConstraints) {
|
|
87
|
-
const env = (0, run_env_1.resolveRunEnv)(target);
|
|
88
|
-
const projectRoot = env.projectPath;
|
|
89
|
-
const result = {
|
|
90
|
-
hasDrift: false,
|
|
91
|
-
notInjected: false,
|
|
92
|
-
duplicateHeading: false,
|
|
93
|
-
fixHint: exports.INJECTION_DRIFT_FIX_HINT,
|
|
94
|
-
};
|
|
95
|
-
const injected = (0, injection_writer_1.resolveInjectionTarget)(projectRoot);
|
|
96
|
-
if (!injected) {
|
|
97
|
-
// 两处均无标记段 = 未注入,不算漂移(check 不警告)。
|
|
98
|
-
// 重复章节仍如实记录供 report 提示:旧落点 CLAUDE.md 优先,其次 AGENTS.md。
|
|
99
|
-
const legacy = (0, injection_writer_1.readIfExists)(path.join(projectRoot, 'CLAUDE.md')) ??
|
|
100
|
-
(0, injection_writer_1.readIfExists)(path.join(projectRoot, 'AGENTS.md'));
|
|
101
|
-
if (legacy !== null) {
|
|
102
|
-
result.duplicateHeading = (0, injection_writer_1.countGovernanceHeadings)(legacy) > 1;
|
|
103
|
-
}
|
|
104
|
-
result.notInjected = true;
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
result.injectionFile = injected.file;
|
|
108
|
-
const { content, startIdx, endIdx } = injected;
|
|
109
|
-
// 重复章节:全文统计治理标题数(严格计数 injection-writer.countGovernanceHeadings,#83)
|
|
110
|
-
const headingCount = (0, injection_writer_1.countGovernanceHeadings)(content);
|
|
111
|
-
result.duplicateHeading = headingCount > 1;
|
|
112
|
-
const actualSection = content.slice(startIdx, endIdx + injection_renderer_1.CONSTRAINTS_END_MARKER.length);
|
|
113
|
-
// 1. 版本漂移
|
|
114
|
-
const versionMatch = VERSION_LINE_RE.exec(actualSection);
|
|
115
|
-
const actualVersion = versionMatch ? versionMatch[1] : '(缺失)';
|
|
116
|
-
if (actualVersion !== currentVersion) {
|
|
117
|
-
result.versionDrift = { expected: currentVersion, actual: actualVersion };
|
|
118
|
-
}
|
|
119
|
-
// 2. 内容漂移(条目级:期望渲染 vs 实际段)
|
|
120
|
-
const expectedSection = (0, injection_renderer_1.renderConstraintsSection)(expectedConstraints ?? (0, effective_constraints_1.getEffectiveConstraints)(env), currentVersion);
|
|
121
|
-
const expectedLines = new Set(significantLines(expectedSection));
|
|
122
|
-
const actualLines = new Set(significantLines(actualSection));
|
|
123
|
-
const missing = [...expectedLines].filter(l => !actualLines.has(l));
|
|
124
|
-
const extra = [...actualLines].filter(l => !expectedLines.has(l));
|
|
125
|
-
if (missing.length > 0 || extra.length > 0) {
|
|
126
|
-
result.contentDrift = { missing, extra };
|
|
127
|
-
}
|
|
128
|
-
result.hasDrift = Boolean(result.versionDrift) || Boolean(result.contentDrift) || result.duplicateHeading;
|
|
129
|
-
return result;
|
|
130
|
-
}
|
|
131
|
-
//# sourceMappingURL=injection-drift.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injection-drift.js","sourceRoot":"","sources":["../../../src/core/constraints/injection-drift.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLAUDE.md 约束注入段渲染(ADR-0001)
|
|
3
|
-
*
|
|
4
|
-
* 纯函数:输入生效约束集 + harness 版本,输出标记区间的期望文本。
|
|
5
|
-
* 与写文件分离——init 注入与 P6 注入漂移校验(期望 vs 实际)共用此渲染。
|
|
6
|
-
*/
|
|
7
|
-
import type { Constraint } from '../../types/constraint';
|
|
8
|
-
/** 约束注入段开始标记 */
|
|
9
|
-
export declare const CONSTRAINTS_START_MARKER = "<!-- HARNESS_CONSTRAINTS_START -->";
|
|
10
|
-
/** 约束注入段结束标记 */
|
|
11
|
-
export declare const CONSTRAINTS_END_MARKER = "<!-- HARNESS_CONSTRAINTS_END -->";
|
|
12
|
-
/**
|
|
13
|
-
* 渲染 CLAUDE.md 约束注入段(含 START/END 标记,不含 `## Governance Rules` 标题)
|
|
14
|
-
*
|
|
15
|
-
* 结构:### Iron Laws / ### Guidelines / ### Prompts(行为约束),
|
|
16
|
-
* 条目为 `- **id**: promptInjection`;无 promptInjection 的 check 条目
|
|
17
|
-
* (如 docs_freshness)不出现在注入段。返回文本以换行结尾。
|
|
18
|
-
*
|
|
19
|
-
* @param constraints 生效约束集(getEffectiveConstraints 的输出)
|
|
20
|
-
* @param version harness 版本号(写入 `<!-- version: x -->` 供漂移校验)
|
|
21
|
-
*/
|
|
22
|
-
export declare function renderConstraintsSection(constraints: Constraint[], version: string): string;
|
|
23
|
-
//# sourceMappingURL=injection-renderer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injection-renderer.d.ts","sourceRoot":"","sources":["../../../src/core/constraints/injection-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,gBAAgB;AAChB,eAAO,MAAM,wBAAwB,uCAAuC,CAAC;AAC7E,gBAAgB;AAChB,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmB3F"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* CLAUDE.md 约束注入段渲染(ADR-0001)
|
|
4
|
-
*
|
|
5
|
-
* 纯函数:输入生效约束集 + harness 版本,输出标记区间的期望文本。
|
|
6
|
-
* 与写文件分离——init 注入与 P6 注入漂移校验(期望 vs 实际)共用此渲染。
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.CONSTRAINTS_END_MARKER = exports.CONSTRAINTS_START_MARKER = void 0;
|
|
10
|
-
exports.renderConstraintsSection = renderConstraintsSection;
|
|
11
|
-
/** 约束注入段开始标记 */
|
|
12
|
-
exports.CONSTRAINTS_START_MARKER = '<!-- HARNESS_CONSTRAINTS_START -->';
|
|
13
|
-
/** 约束注入段结束标记 */
|
|
14
|
-
exports.CONSTRAINTS_END_MARKER = '<!-- HARNESS_CONSTRAINTS_END -->';
|
|
15
|
-
/**
|
|
16
|
-
* 渲染 CLAUDE.md 约束注入段(含 START/END 标记,不含 `## Governance Rules` 标题)
|
|
17
|
-
*
|
|
18
|
-
* 结构:### Iron Laws / ### Guidelines / ### Prompts(行为约束),
|
|
19
|
-
* 条目为 `- **id**: promptInjection`;无 promptInjection 的 check 条目
|
|
20
|
-
* (如 docs_freshness)不出现在注入段。返回文本以换行结尾。
|
|
21
|
-
*
|
|
22
|
-
* @param constraints 生效约束集(getEffectiveConstraints 的输出)
|
|
23
|
-
* @param version harness 版本号(写入 `<!-- version: x -->` 供漂移校验)
|
|
24
|
-
*/
|
|
25
|
-
function renderConstraintsSection(constraints, version) {
|
|
26
|
-
const lines = [exports.CONSTRAINTS_START_MARKER, `<!-- version: ${version} -->`];
|
|
27
|
-
const renderGroup = (level, heading, first) => {
|
|
28
|
-
const items = constraints.filter(c => c.level === level && c.promptInjection);
|
|
29
|
-
if (items.length === 0)
|
|
30
|
-
return;
|
|
31
|
-
if (!first)
|
|
32
|
-
lines.push('');
|
|
33
|
-
lines.push(heading);
|
|
34
|
-
for (const c of items) {
|
|
35
|
-
lines.push(`- **${c.id}**: ${c.promptInjection}`);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
renderGroup('iron_law', '### Iron Laws (违反将阻断)', true);
|
|
39
|
-
renderGroup('guideline', '### Guidelines (应遵循)', lines.length === 2);
|
|
40
|
-
renderGroup('prompt', '### Prompts (行为约束)', lines.length === 2);
|
|
41
|
-
lines.push(exports.CONSTRAINTS_END_MARKER);
|
|
42
|
-
return lines.join('\n') + '\n';
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=injection-renderer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injection-renderer.js","sourceRoot":"","sources":["../../../src/core/constraints/injection-renderer.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAmBH,4DAmBC;AAlCD,gBAAgB;AACH,QAAA,wBAAwB,GAAG,oCAAoC,CAAC;AAC7E,gBAAgB;AACH,QAAA,sBAAsB,GAAG,kCAAkC,CAAC;AAEzE;;;;;;;;;GASG;AACH,SAAgB,wBAAwB,CAAC,WAAyB,EAAE,OAAe;IACjF,MAAM,KAAK,GAAa,CAAC,gCAAwB,EAAE,iBAAiB,OAAO,MAAM,CAAC,CAAC;IAEnF,MAAM,WAAW,GAAG,CAAC,KAA0C,EAAE,OAAe,EAAE,KAAc,EAAE,EAAE;QAClG,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC;QAC9E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,IAAI,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,WAAW,CAAC,UAAU,EAAE,uBAAuB,EAAE,IAAI,CAAC,CAAC;IACvD,WAAW,CAAC,WAAW,EAAE,sBAAsB,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IACrE,WAAW,CAAC,QAAQ,EAAE,oBAAoB,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IAEhE,KAAK,CAAC,IAAI,CAAC,8BAAsB,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* check 命令注入漂移警告测试(ADR-0001 决策 7,P6)
|
|
3
|
-
*
|
|
4
|
-
* 警告不阻断:漂移项目跑 check 仍 0 退出;版本漂移单独显眼警告;
|
|
5
|
-
* 无漂移零输出。使用真实临时目录(漂移检测读真实 fs),
|
|
6
|
-
* 仅 mock checker(直接判过)与 git 调用。
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import * as fs from 'fs';
|
|
10
|
-
import { captureIO, type CapturingIO } from '../../command-contract';
|
|
11
|
-
import * as path from 'path';
|
|
12
|
-
import { check } from '../check';
|
|
13
|
-
import { renderConstraintsSection } from '../../../core/constraints/injection-renderer';
|
|
14
|
-
import { getEffectiveConstraints } from '../../../core/effective-constraints';
|
|
15
|
-
import { createProjectFixture } from '../../../test-setup/project-fixture';
|
|
16
|
-
|
|
17
|
-
// 命令 per-run 构造 checker(harness#88):构造替身即控制 checkConstraints 返回值
|
|
18
|
-
const mockChecker = { checkConstraints: jest.fn() };
|
|
19
|
-
jest.mock('../../../core/constraints/checker', () => ({
|
|
20
|
-
ConstraintChecker: jest.fn(function () {
|
|
21
|
-
return mockChecker;
|
|
22
|
-
}),
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
// 命令 per-run 锚根构造收集器(harness#139):构造替身即拦截 trace 落盘
|
|
26
|
-
jest.mock('../../../monitoring/traces', () => ({
|
|
27
|
-
TraceCollector: jest.fn(function () {
|
|
28
|
-
return { record: jest.fn() };
|
|
29
|
-
}),
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
|
-
jest.mock('../../../utils/exec', () => ({
|
|
33
|
-
execAsync: jest.fn().mockResolvedValue({ stdout: '', stderr: '' }),
|
|
34
|
-
}));
|
|
35
|
-
|
|
36
|
-
jest.mock('child_process', () => ({
|
|
37
|
-
exec: jest.fn(),
|
|
38
|
-
execSync: jest.fn(() => Buffer.from('')),
|
|
39
|
-
}));
|
|
40
|
-
|
|
41
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
42
|
-
const REAL_VERSION = require('../../../../package.json').version as string;
|
|
43
|
-
|
|
44
|
-
function writeClaudeMd(root: string, version: string): void {
|
|
45
|
-
const section =
|
|
46
|
-
'## Governance Rules\n' + renderConstraintsSection(getEffectiveConstraints(root), version);
|
|
47
|
-
fs.writeFileSync(path.join(root, 'CLAUDE.md'), `# Test Project\n\n${section}`, 'utf-8');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
describe('check 命令注入漂移警告', () => {
|
|
51
|
-
let io: CapturingIO;
|
|
52
|
-
|
|
53
|
-
beforeEach(() => {
|
|
54
|
-
|
|
55
|
-
io = captureIO();
|
|
56
|
-
jest.clearAllMocks();
|
|
57
|
-
mockChecker.checkConstraints.mockResolvedValue({
|
|
58
|
-
passed: true,
|
|
59
|
-
ironLaws: [],
|
|
60
|
-
guidelines: [],
|
|
61
|
-
warningCount: 0,
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const outputText = () => io.outText();
|
|
66
|
-
|
|
67
|
-
it('版本漂移:黄色警告块 + ⚠️⚠️ 版本行,但不阻断(exit 未调用,仍判通过)', async () => {
|
|
68
|
-
const root = createProjectFixture({ name: 'harness-check-drift-test' });
|
|
69
|
-
writeClaudeMd(root, '0.0.1-old');
|
|
70
|
-
|
|
71
|
-
const result = await check({ preset: 'standard', staged: false, projectPath: root }, io);
|
|
72
|
-
|
|
73
|
-
const output = outputText();
|
|
74
|
-
expect(output).toContain('约束注入漂移');
|
|
75
|
-
expect(output).toContain('⚠️⚠️');
|
|
76
|
-
expect(output).toContain('agent 上下文中的规则与已安装 harness 版本不一致');
|
|
77
|
-
expect(output).toContain('0.0.1-old');
|
|
78
|
-
expect(output).toContain('npx @dommaker/harness init');
|
|
79
|
-
// 不阻断:检查仍通过、未调用 process.exit
|
|
80
|
-
expect(output).toContain('约束检查通过');
|
|
81
|
-
expect(result.kind).toBe('ok');
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('内容漂移:手改一条 → 警告块含缺失/多余计数,exit 未调用', async () => {
|
|
85
|
-
const root = createProjectFixture({ name: 'harness-check-drift-test' });
|
|
86
|
-
writeClaudeMd(root, REAL_VERSION);
|
|
87
|
-
const claudeMdPath = path.join(root, 'CLAUDE.md');
|
|
88
|
-
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
89
|
-
const originalLine = content.split('\n').find(l => l.startsWith('- **'))!;
|
|
90
|
-
fs.writeFileSync(claudeMdPath, content.replace(originalLine, originalLine.replace(/: .+$/, ': 篡改')), 'utf-8');
|
|
91
|
-
|
|
92
|
-
const result = await check({ preset: 'standard', staged: false, projectPath: root }, io);
|
|
93
|
-
|
|
94
|
-
const output = outputText();
|
|
95
|
-
expect(output).toContain('内容漂移: 缺失 1 条 / 多余 1 条');
|
|
96
|
-
expect(output).toContain('约束检查通过');
|
|
97
|
-
expect(result.kind).toBe('ok');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('无漂移:零警告输出(不增加噪音)', async () => {
|
|
101
|
-
const root = createProjectFixture({ name: 'harness-check-drift-test' });
|
|
102
|
-
writeClaudeMd(root, REAL_VERSION);
|
|
103
|
-
|
|
104
|
-
const result = await check({ preset: 'standard', staged: false, projectPath: root }, io);
|
|
105
|
-
|
|
106
|
-
const output = outputText();
|
|
107
|
-
expect(output).not.toContain('注入漂移');
|
|
108
|
-
expect(output).toContain('约束检查通过');
|
|
109
|
-
expect(result.kind).toBe('ok');
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('未注入(无 CLAUDE.md):不警告', async () => {
|
|
113
|
-
const root = createProjectFixture({ name: 'harness-check-drift-test' });
|
|
114
|
-
|
|
115
|
-
const result = await check({ preset: 'standard', staged: false, projectPath: root }, io);
|
|
116
|
-
|
|
117
|
-
expect(outputText()).not.toContain('注入漂移');
|
|
118
|
-
expect(result.kind).toBe('ok');
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// ── 生效集来源与漂移比对的同一性(ADR-0023 步骤 4.5)──────────────────
|
|
122
|
-
// 改前 CLI 给 -p 塞了缺省值 'standard',「没传」与「传了」不可区分,
|
|
123
|
-
// 于是「--preset 仅在无自定义配置时覆盖」这条规则恒被触发:项目 config.yml 的
|
|
124
|
-
// preset 静默失效,而漂移侧按 config.yml 算 → 两边稳定对不上(该报的漂移不报)。
|
|
125
|
-
|
|
126
|
-
it('config.yml 的 preset 不再被 CLI 缺省顶掉:不带 -p 按 relaxed 执法且零漂移', async () => {
|
|
127
|
-
const root = createProjectFixture({
|
|
128
|
-
name: 'harness-check-drift-relaxed',
|
|
129
|
-
config: 'preset: relaxed\n',
|
|
130
|
-
});
|
|
131
|
-
writeClaudeMd(root, REAL_VERSION); // getEffectiveConstraints(root) 走 config.yml = relaxed
|
|
132
|
-
|
|
133
|
-
const result = await check({ staged: false, projectPath: root }, io);
|
|
134
|
-
|
|
135
|
-
// relaxed 裁掉的内置条目会出现在「已禁用约束」行——改前 CLI 塞了 standard,这行根本不出现
|
|
136
|
-
const output = outputText();
|
|
137
|
-
expect(output).toContain('已禁用约束:');
|
|
138
|
-
expect(output).not.toContain('内容漂移');
|
|
139
|
-
expect(output).toContain('约束检查通过');
|
|
140
|
-
expect(result.kind).toBe('ok');
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('显式 -p 时,漂移比对用的就是本 run 实际执法的那份', async () => {
|
|
144
|
-
const root = createProjectFixture({
|
|
145
|
-
name: 'harness-check-drift-override',
|
|
146
|
-
config: 'preset: relaxed\n',
|
|
147
|
-
});
|
|
148
|
-
writeClaudeMd(root, REAL_VERSION); // 段里是 relaxed 的少数条目
|
|
149
|
-
|
|
150
|
-
await check({ preset: 'standard', staged: false, projectPath: root }, io);
|
|
151
|
-
|
|
152
|
-
// standard 不裁条目(无「已禁用约束」行),且期望段 = 本 run 执法的 standard
|
|
153
|
-
// → 段里条目只少不多,报「缺失 N 条 / 多余 0 条」
|
|
154
|
-
const output = outputText();
|
|
155
|
-
expect(output).not.toContain('已禁用约束:');
|
|
156
|
-
expect(output).toMatch(/内容漂移: 缺失 [1-9]\d* 条 \/ 多余 0 条/);
|
|
157
|
-
});
|
|
158
|
-
});
|