@warpgogol/forge 5.3.3 → 6.0.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 +8 -0
- package/bin/cli.ts +7 -2
- package/dist/bin/cli.js +7 -2
- package/dist/bin/cli.js.map +1 -1
- package/dist/os/adr/adr.module.d.ts.map +1 -1
- package/dist/os/adr/adr.module.js +2 -0
- package/dist/os/adr/adr.module.js.map +1 -1
- package/dist/os/audit/audit.module.d.ts.map +1 -1
- package/dist/os/audit/audit.module.js +2 -0
- package/dist/os/audit/audit.module.js.map +1 -1
- package/dist/os/compass/compass.module.d.ts.map +1 -1
- package/dist/os/compass/compass.module.js +48 -16
- package/dist/os/compass/compass.module.js.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.d.ts +2 -0
- package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.js +39 -9
- package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-docs-validate.d.ts +13 -0
- package/dist/os/compass/handlers/compass-docs-validate.d.ts.map +1 -0
- package/dist/os/compass/handlers/compass-docs-validate.js +326 -0
- package/dist/os/compass/handlers/compass-docs-validate.js.map +1 -0
- package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-inventory.js +5 -2
- package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
- package/dist/os/compass/handlers/summary-record.d.ts +17 -3
- package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
- package/dist/os/compass/handlers/summary-record.js +107 -10
- package/dist/os/compass/handlers/summary-record.js.map +1 -1
- package/dist/os/compass/handlers/tests/forge-yaml-fixture.d.ts +18 -0
- package/dist/os/compass/handlers/tests/forge-yaml-fixture.d.ts.map +1 -0
- package/dist/os/compass/handlers/tests/forge-yaml-fixture.js +64 -0
- package/dist/os/compass/handlers/tests/forge-yaml-fixture.js.map +1 -0
- package/dist/os/compass/policy.d.ts +6 -1
- package/dist/os/compass/policy.d.ts.map +1 -1
- package/dist/os/compass/policy.js +8 -2
- package/dist/os/compass/policy.js.map +1 -1
- package/dist/os/core/core.module.d.ts.map +1 -1
- package/dist/os/core/core.module.js +124 -73
- package/dist/os/core/core.module.js.map +1 -1
- package/dist/os/exploration/exploration.module.d.ts.map +1 -1
- package/dist/os/exploration/exploration.module.js +3 -0
- package/dist/os/exploration/exploration.module.js.map +1 -1
- package/dist/os/mission/handlers/archive.d.ts.map +1 -1
- package/dist/os/mission/handlers/archive.js +1 -2
- package/dist/os/mission/handlers/archive.js.map +1 -1
- package/dist/os/naming/naming.module.d.ts.map +1 -1
- package/dist/os/naming/naming.module.js +9 -2
- package/dist/os/naming/naming.module.js.map +1 -1
- package/dist/os/notes/notes.module.d.ts.map +1 -1
- package/dist/os/notes/notes.module.js +17 -6
- package/dist/os/notes/notes.module.js.map +1 -1
- package/dist/os/plan/plan.module.d.ts.map +1 -1
- package/dist/os/plan/plan.module.js +2 -0
- package/dist/os/plan/plan.module.js.map +1 -1
- package/dist/os/plugin/plugin.module.d.ts.map +1 -1
- package/dist/os/plugin/plugin.module.js +9 -2
- package/dist/os/plugin/plugin.module.js.map +1 -1
- package/dist/os/program/program.module.d.ts.map +1 -1
- package/dist/os/program/program.module.js +19 -4
- package/dist/os/program/program.module.js.map +1 -1
- package/dist/os/queue/handlers/queue-validate.d.ts.map +1 -1
- package/dist/os/queue/handlers/queue-validate.js +154 -7
- package/dist/os/queue/handlers/queue-validate.js.map +1 -1
- package/dist/os/queue/manifest.d.ts +17 -1
- package/dist/os/queue/manifest.d.ts.map +1 -1
- package/dist/os/queue/manifest.js +127 -6
- package/dist/os/queue/manifest.js.map +1 -1
- package/dist/os/queue/queue.module.d.ts.map +1 -1
- package/dist/os/queue/queue.module.js +32 -4
- package/dist/os/queue/queue.module.js.map +1 -1
- package/dist/os/queue/types.d.ts +100 -1
- package/dist/os/queue/types.d.ts.map +1 -1
- package/dist/os/queue/types.js +44 -0
- package/dist/os/queue/types.js.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.js +28 -5
- package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
- package/dist/os/rfc/handlers/validate.js +1 -1
- package/dist/os/rfc/rfc.module.d.ts.map +1 -1
- package/dist/os/rfc/rfc.module.js +27 -3
- package/dist/os/rfc/rfc.module.js.map +1 -1
- package/dist/os/rfc/types.d.ts +11 -0
- package/dist/os/rfc/types.d.ts.map +1 -1
- package/dist/os/rfc/types.js +1 -0
- package/dist/os/rfc/types.js.map +1 -1
- package/dist/os/rfc/verification-evidence.d.ts +21 -0
- package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
- package/dist/os/rfc/verification-evidence.js +140 -23
- package/dist/os/rfc/verification-evidence.js.map +1 -1
- package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
- package/dist/os/rfc/verification-refresh.js +72 -37
- package/dist/os/rfc/verification-refresh.js.map +1 -1
- package/dist/os/session/handlers/save.d.ts.map +1 -1
- package/dist/os/session/handlers/save.js +46 -5
- package/dist/os/session/handlers/save.js.map +1 -1
- package/dist/os/session/session.module.d.ts.map +1 -1
- package/dist/os/session/session.module.js +5 -0
- package/dist/os/session/session.module.js.map +1 -1
- package/dist/os/spec/live-spec-merge.d.ts.map +1 -1
- package/dist/os/spec/live-spec-merge.js +55 -134
- package/dist/os/spec/live-spec-merge.js.map +1 -1
- package/dist/os/spec/live-spec-rebuild.d.ts +32 -0
- package/dist/os/spec/live-spec-rebuild.d.ts.map +1 -0
- package/dist/os/spec/live-spec-rebuild.js +272 -0
- package/dist/os/spec/live-spec-rebuild.js.map +1 -0
- package/dist/os/spec/live-spec-shared.d.ts +62 -0
- package/dist/os/spec/live-spec-shared.d.ts.map +1 -0
- package/dist/os/spec/live-spec-shared.js +315 -0
- package/dist/os/spec/live-spec-shared.js.map +1 -0
- package/dist/os/spec/live-spec-types.d.ts +17 -1
- package/dist/os/spec/live-spec-types.d.ts.map +1 -1
- package/dist/os/spec/live-spec-types.js +3 -0
- package/dist/os/spec/live-spec-types.js.map +1 -1
- package/dist/os/spec/live-spec-validate.d.ts.map +1 -1
- package/dist/os/spec/live-spec-validate.js +105 -2
- package/dist/os/spec/live-spec-validate.js.map +1 -1
- package/dist/os/spec/spec-materialize.d.ts +2 -0
- package/dist/os/spec/spec-materialize.d.ts.map +1 -1
- package/dist/os/spec/spec-materialize.js +45 -5
- package/dist/os/spec/spec-materialize.js.map +1 -1
- package/dist/os/spec/spec-schema.d.ts +19 -0
- package/dist/os/spec/spec-schema.d.ts.map +1 -1
- package/dist/os/spec/spec-schema.js +30 -0
- package/dist/os/spec/spec-schema.js.map +1 -1
- package/dist/os/spec/spec-status.d.ts +4 -0
- package/dist/os/spec/spec-status.d.ts.map +1 -1
- package/dist/os/spec/spec-status.js +19 -1
- package/dist/os/spec/spec-status.js.map +1 -1
- package/dist/os/spec/spec-validate.d.ts.map +1 -1
- package/dist/os/spec/spec-validate.js +55 -8
- package/dist/os/spec/spec-validate.js.map +1 -1
- package/dist/os/spec/spec.module.d.ts.map +1 -1
- package/dist/os/spec/spec.module.js +84 -8
- package/dist/os/spec/spec.module.js.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +10 -4
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
- package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
- package/dist/os/werkstatt/werkstatt.module.js +13 -4
- package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
- package/dist/os/workflow/workflow.module.d.ts.map +1 -1
- package/dist/os/workflow/workflow.module.js +13 -5
- package/dist/os/workflow/workflow.module.js.map +1 -1
- package/dist/src/cli-flags.d.ts.map +1 -1
- package/dist/src/cli-flags.js +25 -5
- package/dist/src/cli-flags.js.map +1 -1
- package/dist/src/config/forge-config.d.ts +24 -3
- package/dist/src/config/forge-config.d.ts.map +1 -1
- package/dist/src/config/forge-config.js +38 -7
- package/dist/src/config/forge-config.js.map +1 -1
- package/dist/src/onboarding/create.d.ts.map +1 -1
- package/dist/src/onboarding/create.js +26 -10
- package/dist/src/onboarding/create.js.map +1 -1
- package/dist/src/onboarding/doctor.d.ts.map +1 -1
- package/dist/src/onboarding/doctor.js +49 -2
- package/dist/src/onboarding/doctor.js.map +1 -1
- package/dist/src/onboarding/init.d.ts.map +1 -1
- package/dist/src/onboarding/init.js +8 -3
- package/dist/src/onboarding/init.js.map +1 -1
- package/dist/src/onboarding/upgrade.d.ts.map +1 -1
- package/dist/src/onboarding/upgrade.js +24 -8
- package/dist/src/onboarding/upgrade.js.map +1 -1
- package/dist/src/pipeline-status.d.ts +14 -1
- package/dist/src/pipeline-status.d.ts.map +1 -1
- package/dist/src/pipeline-status.js +28 -8
- package/dist/src/pipeline-status.js.map +1 -1
- package/dist/src/types.d.ts +7 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/generated-marker.d.ts +8 -0
- package/dist/src/utils/generated-marker.d.ts.map +1 -1
- package/dist/src/utils/generated-marker.js +25 -0
- package/dist/src/utils/generated-marker.js.map +1 -1
- package/dist/src/validators/skill-validate.d.ts.map +1 -1
- package/dist/src/validators/skill-validate.js +42 -15
- package/dist/src/validators/skill-validate.js.map +1 -1
- package/os/adr/adr.module.ts +2 -0
- package/os/audit/audit.module.ts +2 -0
- package/os/compass/compass.module.ts +50 -16
- package/os/compass/handlers/compass-audit-handler.ts +50 -9
- package/os/compass/handlers/compass-docs-validate.ts +359 -0
- package/os/compass/handlers/compass-inventory.ts +6 -3
- package/os/compass/handlers/summary-record.ts +118 -10
- package/os/compass/handlers/tests/compass-audit-record.test.ts +2 -1
- package/os/compass/handlers/tests/compass-audit-validate.test.ts +92 -3
- package/os/compass/handlers/tests/compass-docs-validate.test.ts +203 -0
- package/os/compass/handlers/tests/compass-ledger-scope.test.ts +2 -1
- package/os/compass/handlers/tests/compass-policy.test.ts +15 -18
- package/os/compass/handlers/tests/compass-v2-contract.test.ts +38 -0
- package/os/compass/handlers/tests/forge-yaml-fixture.ts +69 -0
- package/os/compass/handlers/tests/summary-record.test.ts +152 -0
- package/os/compass/policy.ts +8 -2
- package/os/core/core.module.ts +147 -75
- package/os/core/docs-archive.test.ts +136 -0
- package/os/exploration/exploration.module.ts +3 -0
- package/os/mission/handlers/archive.ts +1 -2
- package/os/naming/naming.module.ts +9 -2
- package/os/notes/notes.module.ts +17 -6
- package/os/plan/plan-0000-template.md +150 -0
- package/os/plan/plan.module.ts +2 -0
- package/os/plugin/plugin.module.ts +9 -2
- package/os/program/program.module.ts +19 -4
- package/os/queue/decision-ledger.test.ts +163 -0
- package/os/queue/handlers/queue-validate.ts +190 -8
- package/os/queue/manifest.ts +201 -7
- package/os/queue/queue-validate.test.ts +303 -0
- package/os/queue/queue.module.ts +32 -4
- package/os/queue/types.ts +56 -1
- package/os/rfc/handlers/implement-stamp.ts +35 -5
- package/os/rfc/handlers/validate.ts +1 -1
- package/os/rfc/rfc.module.ts +29 -3
- package/os/rfc/types.ts +17 -1
- package/os/rfc/verification-emit.test.ts +305 -0
- package/os/rfc/verification-evidence.ts +155 -24
- package/os/rfc/verification-refresh.test.ts +222 -1
- package/os/rfc/verification-refresh.ts +80 -38
- package/os/session/handlers/save.ts +41 -5
- package/os/session/session.module.ts +5 -0
- package/os/spec/live-spec-idempotency.pbt.test.ts +222 -0
- package/os/spec/live-spec-list-show-validate.test.ts +10 -6
- package/os/spec/live-spec-merge.test.ts +187 -7
- package/os/spec/live-spec-merge.ts +71 -155
- package/os/spec/live-spec-rebuild.test.ts +317 -0
- package/os/spec/live-spec-rebuild.ts +356 -0
- package/os/spec/live-spec-shared.ts +378 -0
- package/os/spec/live-spec-types.ts +21 -1
- package/os/spec/live-spec-validate.test.ts +317 -0
- package/os/spec/live-spec-validate.ts +106 -2
- package/os/spec/spec-materialize.test.ts +192 -0
- package/os/spec/spec-materialize.ts +48 -4
- package/os/spec/spec-schema.ts +49 -0
- package/os/spec/spec-status.ts +24 -0
- package/os/spec/spec-validate.test.ts +66 -0
- package/os/spec/spec-validate.ts +62 -8
- package/os/spec/spec.module.ts +85 -8
- package/os/werkstatt/handlers/werkstatt-operation-validate.ts +10 -4
- package/os/werkstatt/werkstatt.module.ts +13 -4
- package/os/workflow/workflow.module.ts +13 -5
- package/package.json +1 -1
- package/skills/_shared/fo-pipeline-conventions.md +126 -1
- package/skills/fo/fo-compass-annotate/SKILL.md +1 -1
- package/skills/fo/fo-doc-audit/SKILL.md +4 -4
- package/skills/fo/fo-explore/SKILL.md +2 -1
- package/skills/fo/fo-fix/SKILL.md +11 -3
- package/skills/fo/fo-handoff/SKILL.md +6 -8
- package/skills/fo/fo-idea-audit/SKILL.md +1 -1
- package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -2
- package/skills/fo/fo-idea-enhance/SKILL.md +23 -4
- package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +86 -22
- package/skills/fo/fo-idea-implement/SKILL.md +57 -13
- package/skills/fo/fo-idea-plan/SKILL.md +28 -6
- package/skills/fo/fo-review/SKILL.md +69 -8
- package/skills/fo/fo-session-retro/SKILL.md +4 -3
- package/skills/fo/fo-session-save/SKILL.md +1 -1
- package/skills/fo/fo-step-commit/SKILL.md +2 -0
- package/skills/shared/grilling/SKILL.md +12 -0
- package/skills/shared/writing-great-skills/GLOSSARY.md +2 -0
- package/skills/shared/writing-great-skills/SKILL.md +2 -1
- package/src/cli-flags.ts +23 -5
- package/src/config/forge-config.ts +106 -57
- package/src/onboarding/create.ts +25 -9
- package/src/onboarding/doctor.ts +51 -2
- package/src/onboarding/init.ts +8 -3
- package/src/onboarding/upgrade.ts +36 -6
- package/src/pipeline-status.ts +32 -8
- package/src/tests/bindings-schema.test.ts +53 -1
- package/src/tests/cli-flags.test.ts +20 -0
- package/src/tests/cli-output.test.ts +13 -7
- package/src/tests/doctor-bindings.test.ts +7 -2
- package/src/tests/doctor-skills-unmanaged.test.ts +145 -0
- package/src/tests/fixtures/agents-generate-business-before.txt +7 -7
- package/src/tests/forge-config.test.ts +106 -2
- package/src/tests/implement-stamp.test.ts +38 -0
- package/src/tests/session-handlers.test.ts +33 -0
- package/src/tests/skill-validate.test.ts +180 -0
- package/src/tests/upgrade.test.ts +60 -0
- package/src/types.ts +13 -1
- package/src/utils/generated-marker.ts +28 -0
- package/src/validators/skill-validate.ts +43 -16
- package/skills/fo/fo-idea-implement/ADR-FLOW.md +0 -179
- package/skills/fo/fo-review/AXES.md +0 -70
|
@@ -2,16 +2,19 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
|
2
2
|
import { mkdtemp, mkdir, writeFile, readFile, rm } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
5
6
|
import {
|
|
6
7
|
runCompassSummaryRecord,
|
|
7
8
|
parseChangeSummary,
|
|
8
9
|
mergeHistoryIds,
|
|
9
10
|
buildChangeSummaryBlock,
|
|
10
11
|
stripConventionalPrefix,
|
|
12
|
+
stripGitTrailers,
|
|
11
13
|
isValidGovernanceId,
|
|
12
14
|
CHANGE_SUMMARY_WINDOW,
|
|
13
15
|
} from "../summary-record.ts";
|
|
14
16
|
import { resolveCompassPolicy } from "../../policy.ts";
|
|
17
|
+
import { policyWithIdPattern, cleanupForgeYamlFixtures } from "./forge-yaml-fixture.ts";
|
|
15
18
|
import type { ForgeRuntimeContext } from "../../../../src/types.ts";
|
|
16
19
|
|
|
17
20
|
// Generic policy — this path has no forge.yaml, so resolution falls back to
|
|
@@ -159,6 +162,51 @@ describe("compass.summary.record", () => {
|
|
|
159
162
|
expect(missing.exitCode).toBe(1);
|
|
160
163
|
});
|
|
161
164
|
|
|
165
|
+
it("skips auto-inject when the worktree diff already adds a same-ID item (id-in-diff)", async () => {
|
|
166
|
+
execFileSync("git", ["init"], { cwd: root });
|
|
167
|
+
execFileSync("git", ["config", "user.email", "t@t"], { cwd: root });
|
|
168
|
+
execFileSync("git", ["config", "user.name", "T"], { cwd: root });
|
|
169
|
+
await writeFile(join(root, "src", "a.ts"), TS_HEADER(["RFC-0001: existing item."]));
|
|
170
|
+
execFileSync("git", ["add", "-A"], { cwd: root });
|
|
171
|
+
execFileSync("git", ["commit", "-m", "baseline"], { cwd: root });
|
|
172
|
+
// The pending change carries a hand-authored descriptive item for the ID.
|
|
173
|
+
await writeFile(
|
|
174
|
+
join(root, "src", "a.ts"),
|
|
175
|
+
TS_HEADER(["RFC-0001: existing item.", "RFC-1095: descriptive hand-written entry"]),
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const result = await runCompassSummaryRecord(
|
|
179
|
+
makeInput({ id: "RFC-1095", files: ["src/a.ts"], text: "generic subject line" }),
|
|
180
|
+
makeContext(root),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
expect(result.data?.skipped).toEqual([{ file: "src/a.ts", reason: "id-in-diff" }]);
|
|
184
|
+
expect(result.data?.recorded).toEqual([]);
|
|
185
|
+
const source = await readFile(join(root, "src", "a.ts"), "utf8");
|
|
186
|
+
expect(source).not.toContain("generic subject line");
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("still records when the same-ID item already exists at HEAD (consecutive-commit stack)", async () => {
|
|
190
|
+
execFileSync("git", ["init"], { cwd: root });
|
|
191
|
+
execFileSync("git", ["config", "user.email", "t@t"], { cwd: root });
|
|
192
|
+
execFileSync("git", ["config", "user.name", "T"], { cwd: root });
|
|
193
|
+
await writeFile(
|
|
194
|
+
join(root, "src", "a.ts"),
|
|
195
|
+
TS_HEADER(["RFC-1095: step 1 — recorded by the previous commit"]),
|
|
196
|
+
);
|
|
197
|
+
execFileSync("git", ["add", "-A"], { cwd: root });
|
|
198
|
+
execFileSync("git", ["commit", "-m", "baseline"], { cwd: root });
|
|
199
|
+
|
|
200
|
+
const result = await runCompassSummaryRecord(
|
|
201
|
+
makeInput({ id: "RFC-1095", files: ["src/a.ts"], text: "step 2" }),
|
|
202
|
+
makeContext(root),
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
expect(result.data?.recorded).toEqual(["src/a.ts"]);
|
|
206
|
+
const source = await readFile(join(root, "src", "a.ts"), "utf8");
|
|
207
|
+
expect(source).toContain("<item>RFC-1095: step 2</item>");
|
|
208
|
+
});
|
|
209
|
+
|
|
162
210
|
it("defaults item text to the bare ID when --text is absent", async () => {
|
|
163
211
|
await writeFile(join(root, "src", "a.ts"), TS_HEADER([]));
|
|
164
212
|
await runCompassSummaryRecord(
|
|
@@ -190,6 +238,65 @@ describe("compass.summary.record", () => {
|
|
|
190
238
|
expect(source).toContain("<item>RFC-1095: record command</item>");
|
|
191
239
|
expect(source).not.toContain("RFC-1095: RFC-1095");
|
|
192
240
|
});
|
|
241
|
+
|
|
242
|
+
it("strips Generated-with/Co-Authored-By trailer blocks from the recorded item (RFC-1233 AC-1)", async () => {
|
|
243
|
+
await writeFile(join(root, "src", "a.ts"), TS_HEADER([]));
|
|
244
|
+
await runCompassSummaryRecord(
|
|
245
|
+
makeInput({
|
|
246
|
+
id: "RFC-1233",
|
|
247
|
+
files: ["src/a.ts"],
|
|
248
|
+
text: "trailer stripping\n\nGenerated with [Devin](https://devin.ai)\nCo-Authored-By: Devin <bot@users.noreply.github.com>",
|
|
249
|
+
}),
|
|
250
|
+
makeContext(root),
|
|
251
|
+
);
|
|
252
|
+
const source = await readFile(join(root, "src", "a.ts"), "utf8");
|
|
253
|
+
expect(source).toContain("<item>RFC-1233: trailer stripping</item>");
|
|
254
|
+
expect(source).not.toContain("Co-Authored-By");
|
|
255
|
+
expect(source).not.toContain("Generated with");
|
|
256
|
+
expect(source).not.toContain("devin.ai");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("neutralizes a literal star-slash in --text so the item cannot terminate the block comment (RFC-1233 AC-2)", async () => {
|
|
260
|
+
await writeFile(join(root, "src", "a.ts"), TS_HEADER([]));
|
|
261
|
+
await runCompassSummaryRecord(
|
|
262
|
+
makeInput({
|
|
263
|
+
id: "RFC-1233",
|
|
264
|
+
files: ["src/a.ts"],
|
|
265
|
+
text: "glob src" + "/**/*.ts in comments",
|
|
266
|
+
}),
|
|
267
|
+
makeContext(root),
|
|
268
|
+
);
|
|
269
|
+
const source = await readFile(join(root, "src", "a.ts"), "utf8");
|
|
270
|
+
expect(source).toContain("RFC-1233: glob src");
|
|
271
|
+
expect(source.match(CS_BLOCK_RE)).not.toBeNull();
|
|
272
|
+
// The neutralized form keeps both characters readable but cannot close /*.
|
|
273
|
+
expect(source).toContain("glob src/**" + "∕*.ts in comments");
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("keeps a single-line subject identical — negative regression (RFC-1233 AC-3)", async () => {
|
|
277
|
+
await writeFile(join(root, "src", "a.ts"), TS_HEADER([]));
|
|
278
|
+
await runCompassSummaryRecord(
|
|
279
|
+
makeInput({ id: "RFC-1233", files: ["src/a.ts"], text: "plain subject line" }),
|
|
280
|
+
makeContext(root),
|
|
281
|
+
);
|
|
282
|
+
const source = await readFile(join(root, "src", "a.ts"), "utf8");
|
|
283
|
+
expect(source).toContain("<item>RFC-1233: plain subject line</item>");
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it("preserves a Key: value-shaped line when it is not in the trailing block (RFC-1233 AC-4)", async () => {
|
|
287
|
+
await writeFile(join(root, "src", "a.ts"), TS_HEADER([]));
|
|
288
|
+
await runCompassSummaryRecord(
|
|
289
|
+
makeInput({
|
|
290
|
+
id: "RFC-1233",
|
|
291
|
+
files: ["src/a.ts"],
|
|
292
|
+
text: "fix the parser\n\nNote: this line is prose about the fix\nfinal summary line",
|
|
293
|
+
}),
|
|
294
|
+
makeContext(root),
|
|
295
|
+
);
|
|
296
|
+
const source = await readFile(join(root, "src", "a.ts"), "utf8");
|
|
297
|
+
expect(source).toContain("Note: this line is prose about the fix");
|
|
298
|
+
expect(source).toContain("final summary line");
|
|
299
|
+
});
|
|
193
300
|
});
|
|
194
301
|
|
|
195
302
|
describe("summary-record helpers", () => {
|
|
@@ -216,9 +323,54 @@ describe("summary-record helpers", () => {
|
|
|
216
323
|
]);
|
|
217
324
|
});
|
|
218
325
|
|
|
326
|
+
afterEach(() => {
|
|
327
|
+
cleanupForgeYamlFixtures();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("mergeHistoryIds sorts mission-format tokens under their namespace (RFC-1220)", () => {
|
|
331
|
+
const missionPolicy = policyWithIdPattern(
|
|
332
|
+
"\\b(?:[A-Z][A-Z0-9]*-)+\\d+\\b|\\b[a-z][a-z0-9-]*-m\\d{6}\\b",
|
|
333
|
+
);
|
|
334
|
+
expect(mergeHistoryIds(["acme-m000003"], ["acme-m000001", "RFC-0002"], missionPolicy)).toEqual([
|
|
335
|
+
"acme-m000001",
|
|
336
|
+
"acme-m000003",
|
|
337
|
+
"RFC-0002",
|
|
338
|
+
]);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it("mergeHistoryIds appends unparseable admitted tokens last (RFC-1220)", () => {
|
|
342
|
+
const driftPolicy = policyWithIdPattern("\\b(?:[A-Z][A-Z0-9]*-)+\\d+\\b|\\b[A-Z]+-[A-Z]+\\b");
|
|
343
|
+
expect(mergeHistoryIds(["FOO-BAR"], ["RFC-0002", "RFC-0001"], driftPolicy)).toEqual([
|
|
344
|
+
"RFC-0001",
|
|
345
|
+
"RFC-0002",
|
|
346
|
+
"FOO-BAR",
|
|
347
|
+
]);
|
|
348
|
+
});
|
|
349
|
+
|
|
219
350
|
it("buildChangeSummaryBlock omits <history> when empty", () => {
|
|
220
351
|
const block = buildChangeSummaryBlock(["RFC-1: a"], [], "x.ts");
|
|
221
352
|
expect(block).not.toContain("<history>");
|
|
222
353
|
expect(block).toContain("<item>RFC-1: a</item>");
|
|
223
354
|
});
|
|
355
|
+
|
|
356
|
+
it("stripGitTrailers strips a Token:-shaped tail block (RFC-1233)", () => {
|
|
357
|
+
expect(
|
|
358
|
+
stripGitTrailers("subject\n\nbody line\nCo-Authored-By: Devin <bot@x>\nX-RFC: RFC-1233"),
|
|
359
|
+
).toBe("subject\n\nbody line");
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("stripGitTrailers keeps a lone markdown-link tail (no strict trailer line)", () => {
|
|
363
|
+
const msg = "subject\n\nsee [the docs](https://example.com)";
|
|
364
|
+
expect(stripGitTrailers(msg)).toBe(msg);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it("stripGitTrailers on a trailer-only message returns empty", () => {
|
|
368
|
+
expect(stripGitTrailers("Co-Authored-By: Devin <bot@x>")).toBe("");
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it("stripGitTrailers strips empty-value trailers (Token:) — interpret-trailers allows them", () => {
|
|
372
|
+
expect(stripGitTrailers("subject\n\nReviewed-by:\nSigned-off-by: Devin <bot@x>")).toBe(
|
|
373
|
+
"subject",
|
|
374
|
+
);
|
|
375
|
+
});
|
|
224
376
|
});
|
package/os/compass/policy.ts
CHANGED
|
@@ -12,6 +12,7 @@ are authored, how risky they are, and what counts as a governance ID
|
|
|
12
12
|
</MODULE_CONTRACT>
|
|
13
13
|
<CHANGE_SUMMARY>
|
|
14
14
|
<item>RFC-1096: initial policy resolver — generic defaults + profile compass section + bindings.compass overrides.</item>
|
|
15
|
+
<item>RFC-1220: step 1 — widen governance-ID tail regex</item>
|
|
15
16
|
</CHANGE_SUMMARY>
|
|
16
17
|
*/
|
|
17
18
|
|
|
@@ -212,9 +213,14 @@ function compilePattern(key: string, pattern: string, flags?: string): RegExp {
|
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
|
|
215
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* Split a `NAMESPACE-NUMBER` governance ID on its last dash.
|
|
218
|
+
* Mission-format tails (`slug-mNNNNNN`) parse as `{ namespace: slug, numeric: N }`.
|
|
219
|
+
* The `m` stays outside the digit capture — `-(m?\d+)$` would capture `m000175`
|
|
220
|
+
* into the numeric group and produce `NaN` (RFC-1220).
|
|
221
|
+
*/
|
|
216
222
|
export function parseGovernanceIdParts(id: string): { namespace: string; numeric: number } | null {
|
|
217
|
-
const match = id.match(/^(.*)-(\d+)$/);
|
|
223
|
+
const match = id.match(/^(.*)-m?(\d+)$/);
|
|
218
224
|
if (!match) return null;
|
|
219
225
|
return { namespace: match[1]!, numeric: Number(match[2]) };
|
|
220
226
|
}
|