Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/review/content-lane/registry-logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -929,11 +929,14 @@ export function checkContentLaneDeliverable(
changedFiles: readonly string[],
issueTitle?: string,
): ContentLaneDeliverableCheck {
const matchesSpec = (candidate: string): boolean => spec.entryFilePattern.test(candidate) || (spec.providerFilePattern?.test(candidate) ?? false);
// Mirror classifyRegistryPrScope's matchesPattern: test on canonicalize(candidate) while keeping the original
// string for anything user-visible (mentionedPath in the public PR comment).
const matchesSpec = (candidate: string): boolean =>
spec.entryFilePattern.test(canonicalize(candidate)) || (spec.providerFilePattern?.test(canonicalize(candidate)) ?? false);
const mentionedPath = extractPathTokens(issueText).find(matchesSpec);
const titleImplies = !mentionedPath && Boolean(issueTitle && spec.issueTitleImpliesEntryPattern?.test(issueTitle));
if (!mentionedPath && !titleImplies) return { verdict: "not-applicable" };
const delivered = changedFiles.some((file) => matchesSpec(canonicalize(file)));
const delivered = changedFiles.some((file) => matchesSpec(file));
if (delivered) return { verdict: "delivered" };
return { verdict: "missing", mentionedPath: mentionedPath ?? `a registry entry file matching ${spec.entryFilePattern} (implied by this issue's title)` };
}
Expand Down
23 changes: 23 additions & 0 deletions test/unit/content-lane-registry-logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,29 @@ describe("checkContentLaneDeliverable (generic, spec-driven — #content-lane-de
expect(checkContentLaneDeliverable(spec, issueText, ["registry\\subnets\\foo.json"]).verdict).toBe("delivered");
});

it("canonicalizes mixed-case issue-body path tokens while preserving the original mentionedPath (#9667)", () => {
const issueText = "Add the missing surfaces to Registry/Subnets/Foo.json.";
expect(checkContentLaneDeliverable(spec, issueText, ["tests/foo-verify.test.mjs"])).toEqual({
verdict: "missing",
mentionedPath: "Registry/Subnets/Foo.json",
});
expect(checkContentLaneDeliverable(spec, issueText, ["registry/subnets/foo.json"])).toEqual({ verdict: "delivered" });
});

it("keeps all-lowercase issue-body path behavior byte-identical (#9667)", () => {
const issueText = "Add the missing surfaces to registry/subnets/foo.json.";
expect(checkContentLaneDeliverable(spec, issueText, ["tests/foo-verify.test.mjs"])).toEqual({
verdict: "missing",
mentionedPath: "registry/subnets/foo.json",
});
expect(checkContentLaneDeliverable(spec, issueText, ["registry/subnets/foo.json"])).toEqual({ verdict: "delivered" });
});

it("stays not-applicable when the issue body names a path that matches no spec pattern (#9667)", () => {
const issueText = "Update the docs at Docs/Guides/Setup.md.";
expect(checkContentLaneDeliverable(spec, issueText, ["tests/unrelated.test.mjs"])).toEqual({ verdict: "not-applicable" });
});

it("is not-applicable for a spec with no providerFilePattern configured, even if the issue mentions an entry-shaped path (guards the optional-chaining branch)", () => {
const entryOnlySpec: RegistryLaneSpec = { entryFilePattern: SUBNET_ENTRY_PATTERN, collectionField: "surfaces" };
const issueText = "Add registry/subnets/foo.json.";
Expand Down
Loading