feat(plugins): add source-control extension contracts (#2117)

This commit is contained in:
José Almeida
2026-08-13 08:29:29 +01:00
committed by GitHub
parent 064b852884
commit f218880ecb
530 changed files with 39054 additions and 7518 deletions
+33 -1
View File
@@ -318,6 +318,35 @@ export function findAbsenceClaims(content) {
);
}
/**
* Split prose into sentence-sized claim scopes. API names elsewhere in the
* same wrapped Markdown paragraph must not inherit an unrelated absence claim.
* Dots inside identifiers such as `host.storage` are preserved because a
* boundary requires following whitespace or the end of the paragraph.
*
* @param {string} text Paragraph text.
* @returns {string[]} Sentence-sized fragments.
*/
function splitClaimScopes(text) {
return text.split(/[.!?](?:\s+|$)/).filter(Boolean);
}
/**
* API claims in harness Markdown name contracts as inline code. Restricting
* matching to those spans prevents common host words such as `context` from
* being attributed to unrelated phrases like "thread context is unavailable."
*
* @param {string} scope Sentence-sized absence-claim scope.
* @param {RegExp} boundary Escaped live-name matcher.
* @returns {boolean} Whether an inline-code span names the live API.
*/
function scopeMentionsLiveAPI(scope, boundary) {
for (const match of scope.matchAll(/`([^`]+)`/g)) {
if (boundary.test(match[1])) return true;
}
return false;
}
/**
* Resolve the fixed set of harness files this guard scans, de-duplicated by
* physical (symlink-resolved) path.
@@ -423,11 +452,14 @@ export async function validatePluginApiClaims({
const relFile = path.relative(root, file);
for (const claim of claims) {
const claimScopes = splitClaimScopes(claim.text).filter((scope) =>
CLAIM_PATTERNS.some((pattern) => pattern.test(scope)),
);
for (const name of liveNames) {
const boundary = new RegExp(
`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`,
);
if (boundary.test(claim.text)) {
if (claimScopes.some((scope) => scopeMentionsLiveAPI(scope, boundary))) {
findings.push({ file: relFile, line: claim.line, api: name });
}
}