@deftai/directive-core 0.107.0 → 0.108.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/dist/architecture/sor-preflight.js +2 -0
- package/dist/check/cached-orchestrator.js +28 -3
- package/dist/check/named-cause.js +18 -3
- package/dist/codebase/provider.js +7 -1
- package/dist/delivery-attempt/handoff.js +1 -1
- package/dist/design-critique/citation-grammar.d.ts +53 -0
- package/dist/design-critique/citation-grammar.js +303 -0
- package/dist/design-critique/completed-arc-record.d.ts +62 -0
- package/dist/design-critique/completed-arc-record.js +232 -0
- package/dist/freshness/bind.d.ts +32 -3
- package/dist/freshness/bind.js +58 -12
- package/dist/hooks/classify/host-session-identity.d.ts +76 -0
- package/dist/hooks/classify/host-session-identity.js +470 -0
- package/dist/hooks/classify/index.d.ts +3 -2
- package/dist/hooks/classify/index.js +3 -2
- package/dist/hooks/classify/paths.d.ts +7 -0
- package/dist/hooks/classify/paths.js +35 -0
- package/dist/hooks/classify/stdin.d.ts +5 -0
- package/dist/hooks/classify/stdin.js +27 -0
- package/dist/hooks/dispatcher.d.ts +52 -1
- package/dist/hooks/dispatcher.js +538 -45
- package/dist/hooks/fixtures/cases.d.ts +16 -2
- package/dist/hooks/fixtures/cases.js +175 -0
- package/dist/hooks/scope.js +3 -1
- package/dist/init-deposit/agent-hooks.d.ts +2 -1
- package/dist/init-deposit/agent-hooks.js +8 -1
- package/dist/init-deposit/hook-runtime-travel.d.ts +77 -0
- package/dist/init-deposit/hook-runtime-travel.js +269 -0
- package/dist/intake/clause-derivation.js +9 -3
- package/dist/intake/issue-ingest.js +62 -2
- package/dist/intake/platform-capabilities.d.ts +9 -2
- package/dist/intake/platform-capabilities.js +38 -9
- package/dist/orphan-active/evaluate.d.ts +25 -0
- package/dist/orphan-active/evaluate.js +193 -128
- package/dist/orphan-active/index.d.ts +1 -0
- package/dist/orphan-active/index.js +1 -0
- package/dist/orphan-active/issue-state.d.ts +121 -0
- package/dist/orphan-active/issue-state.js +278 -0
- package/dist/platform/cursor-managed-runtime.d.ts +95 -0
- package/dist/platform/cursor-managed-runtime.js +241 -0
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +1 -0
- package/dist/platform/platform-capabilities.d.ts +23 -1
- package/dist/platform/platform-capabilities.js +55 -15
- package/dist/policy/ceremony-dial.js +5 -9
- package/dist/policy/host-hooks.js +4 -9
- package/dist/policy/org-force-on-migration.js +5 -10
- package/dist/policy/plan-extensions.d.ts +14 -2
- package/dist/policy/plan-extensions.js +24 -3
- package/dist/policy/product-signal.js +5 -10
- package/dist/policy/require-human-merge.js +5 -9
- package/dist/policy/resolve.js +77 -16
- package/dist/policy/value-feedback.js +9 -18
- package/dist/pr-closeout-attestable/evaluate.d.ts +80 -0
- package/dist/pr-closeout-attestable/evaluate.js +306 -0
- package/dist/pr-closeout-attestable/index.d.ts +2 -0
- package/dist/pr-closeout-attestable/index.js +2 -0
- package/dist/pr-protected-issues/gh.d.ts +6 -2
- package/dist/pr-protected-issues/gh.js +7 -3
- package/dist/pr-wait-mergeable/cascade.d.ts +9 -1
- package/dist/pr-wait-mergeable/cascade.js +21 -1
- package/dist/pr-wait-mergeable/types.d.ts +2 -0
- package/dist/pr-wait-mergeable/wrappers.d.ts +6 -0
- package/dist/pr-wait-mergeable/wrappers.js +11 -0
- package/dist/preflight/evaluate.d.ts +15 -0
- package/dist/preflight/evaluate.js +29 -3
- package/dist/product-first-done-gate/acceptance-resolver.d.ts +14 -2
- package/dist/product-first-done-gate/acceptance-resolver.js +13 -2
- package/dist/product-first-done-gate/evaluate.js +17 -7
- package/dist/release/cli-drift-report.d.ts +68 -0
- package/dist/release/cli-drift-report.js +189 -0
- package/dist/release/index.d.ts +1 -0
- package/dist/release/index.js +1 -0
- package/dist/release/issue-state-fetch.d.ts +5 -3
- package/dist/release/issue-state-fetch.js +86 -21
- package/dist/release/native-steps.js +1 -0
- package/dist/release/pipeline.js +19 -0
- package/dist/release/types.d.ts +14 -0
- package/dist/render/constants.d.ts +4 -0
- package/dist/render/constants.js +11 -8
- package/dist/render/export-spec.js +31 -5
- package/dist/render/index.d.ts +1 -1
- package/dist/render/index.js +1 -1
- package/dist/render/prd-render.d.ts +4 -1
- package/dist/render/prd-render.js +82 -23
- package/dist/render/project-render.js +14 -7
- package/dist/render/scope-outlook.d.ts +2 -0
- package/dist/render/scope-outlook.js +3 -0
- package/dist/render/spec-render.js +2 -2
- package/dist/resolution/package-manager.d.ts +33 -4
- package/dist/resolution/package-manager.js +210 -9
- package/dist/review-monitor/constants.d.ts +7 -0
- package/dist/review-monitor/constants.js +7 -0
- package/dist/review-monitor/github-lease.d.ts +98 -1
- package/dist/review-monitor/github-lease.js +182 -1
- package/dist/review-monitor/lease-comment.d.ts +36 -0
- package/dist/review-monitor/lease-comment.js +103 -2
- package/dist/scm/call.js +12 -3
- package/dist/scm/design-critique-chip.d.ts +1 -0
- package/dist/scm/design-critique-chip.js +22 -6
- package/dist/scm/gh-rest.d.ts +9 -1
- package/dist/scm/gh-rest.js +103 -0
- package/dist/scm/readiness.d.ts +2 -0
- package/dist/scm/readiness.js +28 -4
- package/dist/scope/project-definition-sync.js +14 -7
- package/dist/session/git.d.ts +24 -0
- package/dist/session/git.js +138 -2
- package/dist/session/occupancy.d.ts +238 -12
- package/dist/session/occupancy.js +815 -29
- package/dist/session/ritual-sentinel.d.ts +5 -0
- package/dist/session/ritual-sentinel.js +5 -0
- package/dist/session/session-ready.d.ts +5 -1
- package/dist/session/session-ready.js +98 -8
- package/dist/session/session-start.d.ts +5 -1
- package/dist/session/session-start.js +32 -17
- package/dist/session/toolchain-preflight.d.ts +13 -3
- package/dist/session/toolchain-preflight.js +93 -18
- package/dist/session/verify-session-ritual.d.ts +11 -0
- package/dist/session/verify-session-ritual.js +60 -15
- package/dist/slice/constants.d.ts +1 -1
- package/dist/spec-authority/constants.d.ts +10 -2
- package/dist/spec-authority/constants.js +53 -8
- package/dist/spec-authority/resolver.d.ts +3 -0
- package/dist/spec-authority/resolver.js +55 -7
- package/dist/subprocess/max-buffer.d.ts +14 -0
- package/dist/subprocess/max-buffer.js +15 -0
- package/dist/swarm/complete-cohort.d.ts +2 -0
- package/dist/swarm/complete-cohort.js +21 -13
- package/dist/swarm/index.d.ts +1 -0
- package/dist/swarm/index.js +1 -0
- package/dist/swarm/launch-cli.js +53 -33
- package/dist/swarm/launch.d.ts +8 -0
- package/dist/swarm/launch.js +63 -43
- package/dist/swarm/pre-dispatch-cli.js +2 -1
- package/dist/swarm/pre-dispatch.js +10 -1
- package/dist/swarm/subagent-status-dir.d.ts +27 -0
- package/dist/swarm/subagent-status-dir.js +42 -0
- package/dist/swarm/worktrees.d.ts +17 -3
- package/dist/swarm/worktrees.js +48 -4
- package/dist/triage/scope/mutations-core.d.ts +2 -6
- package/dist/triage/scope/mutations-core.js +23 -55
- package/dist/triage/scope-drift/add-ignore.js +5 -39
- package/dist/triage/subscribe/index.d.ts +2 -6
- package/dist/triage/subscribe/index.js +15 -65
- package/dist/triage/welcome/writers.js +15 -74
- package/dist/vbrief-build/index.d.ts +2 -1
- package/dist/vbrief-build/index.js +2 -1
- package/dist/vbrief-build/parity-scenarios.js +5 -5
- package/dist/vbrief-build/project-definition-io.d.ts +63 -3
- package/dist/vbrief-build/project-definition-io.js +357 -31
- package/dist/vbrief-build/project-definition-mutation.d.ts +32 -0
- package/dist/vbrief-build/project-definition-mutation.js +43 -0
- package/dist/vbrief-validate/conformance.d.ts +1 -0
- package/dist/vbrief-validate/conformance.js +85 -8
- package/dist/vbrief-validate/main.js +2 -0
- package/dist/vbrief-validate/precutover.js +5 -10
- package/dist/verify-ac/clauses.d.ts +62 -2
- package/dist/verify-ac/clauses.js +183 -111
- package/dist/verify-ac/index.d.ts +1 -1
- package/dist/verify-ac/index.js +1 -1
- package/dist/verify-env/node-runtime.d.ts +8 -4
- package/dist/verify-env/node-runtime.js +9 -6
- package/dist/verify-env/toolchain-check.d.ts +35 -3
- package/dist/verify-env/toolchain-check.js +155 -36
- package/dist/verify-source/project-definition-mutation-boundary.d.ts +104 -0
- package/dist/verify-source/project-definition-mutation-boundary.js +326 -0
- package/package.json +7 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { GitCommandError, GitNotFoundError, gitStagedFiles, gitTrackedFiles, } from "../encoding/git.js";
|
|
4
4
|
import { fnmatchCase } from "../encoding/text.js";
|
|
@@ -71,8 +71,21 @@ export const ITEM_CORE = new Set([
|
|
|
71
71
|
// (accepted via EXTENSION_PREFIXES). Bare evidence/disposition fail #1620.
|
|
72
72
|
]);
|
|
73
73
|
export const EXTENSION_PREFIXES = ["x-directive/", "x-vbrief/", "x-xbrief/"];
|
|
74
|
+
const SAFE_FINDING_KEY = /^[A-Za-z][A-Za-z0-9._/-]{0,63}$/;
|
|
75
|
+
const SENSITIVE_FINDING_KEY = /(?:auth|credential|password|private|secret|token|api.?key)/i;
|
|
76
|
+
/**
|
|
77
|
+
* Bounded presentation of a raw finding key (#3796). `finding.key` stays exact
|
|
78
|
+
* for machine consumers; only this rendered form is sanitised, so a hostile or
|
|
79
|
+
* sensitive key cannot ride a stderr diagnostic out of the process.
|
|
80
|
+
*/
|
|
81
|
+
function renderFindingKey(key) {
|
|
82
|
+
return SAFE_FINDING_KEY.test(key) && !SENSITIVE_FINDING_KEY.test(key)
|
|
83
|
+
? key
|
|
84
|
+
: `<redacted-key length=${[...key].length}>`;
|
|
85
|
+
}
|
|
74
86
|
export function renderFinding(finding) {
|
|
75
|
-
return ` ${finding.path} [${finding.level}] bare key
|
|
87
|
+
return (` ${finding.path} [${finding.level}] bare key ` +
|
|
88
|
+
`'${renderFindingKey(finding.key)}' at ${finding.location}`);
|
|
76
89
|
}
|
|
77
90
|
function isConformant(key, core) {
|
|
78
91
|
if (core.has(key)) {
|
|
@@ -244,21 +257,85 @@ export function evaluateConformance(projectRoot, options = {}) {
|
|
|
244
257
|
}
|
|
245
258
|
const candidates = relPaths
|
|
246
259
|
.map((p) => p.replace(/\\/g, "/"))
|
|
247
|
-
.filter((posix) => isVbriefPath(posix) && !isAllowListed(posix, customGlobs))
|
|
260
|
+
.filter((posix) => isVbriefPath(posix) && !isAllowListed(posix, customGlobs))
|
|
261
|
+
.map((posix) => ({ displayPath: posix, fullPath: join(root, posix), configured: false }));
|
|
262
|
+
const configuredPath = options.projectDefinitionPath?.trim();
|
|
263
|
+
if (configuredPath) {
|
|
264
|
+
const lexicalPath = resolve(root, configuredPath);
|
|
265
|
+
if (!existsSync(lexicalPath)) {
|
|
266
|
+
return {
|
|
267
|
+
exitCode: 2,
|
|
268
|
+
findings: [],
|
|
269
|
+
message: "❌ verify_vbrief_conformance: configured PROJECT-DEFINITION does not exist.\n" +
|
|
270
|
+
" Recovery: fix or unset DEFT_PROJECT_PATH, then rerun conformance.",
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
let fullPath;
|
|
274
|
+
try {
|
|
275
|
+
fullPath = realpathSync(lexicalPath);
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
return {
|
|
279
|
+
exitCode: 2,
|
|
280
|
+
findings: [],
|
|
281
|
+
message: "❌ verify_vbrief_conformance: configured PROJECT-DEFINITION is unreadable.\n" +
|
|
282
|
+
" Recovery: fix its permissions or DEFT_PROJECT_PATH, then rerun conformance.",
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
const existing = candidates.find((candidate) => {
|
|
286
|
+
try {
|
|
287
|
+
return realpathSync(candidate.fullPath) === fullPath;
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
return resolve(candidate.fullPath) === fullPath;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
if (existing === undefined) {
|
|
294
|
+
candidates.push({
|
|
295
|
+
displayPath: "<configured PROJECT-DEFINITION>",
|
|
296
|
+
fullPath,
|
|
297
|
+
configured: true,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
existing.displayPath = "<configured PROJECT-DEFINITION>";
|
|
302
|
+
existing.fullPath = fullPath;
|
|
303
|
+
existing.configured = true;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
248
306
|
const findings = [];
|
|
249
|
-
for (const
|
|
250
|
-
const full = join(root, posix);
|
|
307
|
+
for (const candidate of candidates) {
|
|
251
308
|
let text;
|
|
252
309
|
try {
|
|
253
|
-
text = readFileSync(
|
|
310
|
+
text = readFileSync(candidate.fullPath, "utf8");
|
|
254
311
|
}
|
|
255
312
|
catch {
|
|
313
|
+
if (candidate.configured) {
|
|
314
|
+
return {
|
|
315
|
+
exitCode: 2,
|
|
316
|
+
findings,
|
|
317
|
+
message: "❌ verify_vbrief_conformance: configured PROJECT-DEFINITION is unreadable.\n" +
|
|
318
|
+
" Recovery: fix its permissions or DEFT_PROJECT_PATH, then rerun conformance.",
|
|
319
|
+
};
|
|
320
|
+
}
|
|
256
321
|
continue;
|
|
257
322
|
}
|
|
323
|
+
let data;
|
|
258
324
|
try {
|
|
259
|
-
|
|
325
|
+
data = JSON.parse(text);
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
if (candidate.configured) {
|
|
329
|
+
return {
|
|
330
|
+
exitCode: 2,
|
|
331
|
+
findings,
|
|
332
|
+
message: "❌ verify_vbrief_conformance: configured PROJECT-DEFINITION is not valid JSON.\n" +
|
|
333
|
+
" Recovery: repair the JSON, then rerun conformance.",
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
continue;
|
|
260
337
|
}
|
|
261
|
-
|
|
338
|
+
findings.push(...scanVbrief(candidate.displayPath, data));
|
|
262
339
|
}
|
|
263
340
|
if (findings.length > 0) {
|
|
264
341
|
const uniquePaths = new Set(findings.map((f) => f.path));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { resolveLifecycleLayout } from "../layout/resolve.js";
|
|
4
|
+
import { ENV_PROJECT_PATH } from "../vbrief-build/project-definition-io.js";
|
|
4
5
|
import { evaluateConformance } from "./conformance.js";
|
|
5
6
|
import { USAGE } from "./constants.js";
|
|
6
7
|
import { validateAll } from "./validate-all.js";
|
|
@@ -130,6 +131,7 @@ export function runConformance(argv) {
|
|
|
130
131
|
const { exitCode, message } = evaluateConformance(resolve(projectRoot), {
|
|
131
132
|
mode,
|
|
132
133
|
allowListPath,
|
|
134
|
+
projectDefinitionPath: process.env[ENV_PROJECT_PATH] ?? null,
|
|
133
135
|
});
|
|
134
136
|
if (exitCode === 0) {
|
|
135
137
|
if (!quiet) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { resolveLifecycleLayout, resolveLifecycleRoot
|
|
4
|
-
import {
|
|
5
|
-
import { isFullSpecState, isGreenfieldSpecExport } from "../spec-authority/resolver.js";
|
|
3
|
+
import { resolveLifecycleLayout, resolveLifecycleRoot } from "../layout/resolve.js";
|
|
4
|
+
import { GENERATED_SPEC_PURPOSE } from "../spec-authority/constants.js";
|
|
5
|
+
import { contentHasResolvedSpecSource, isFullSpecState, isGreenfieldSpecExport, } from "../spec-authority/resolver.js";
|
|
6
6
|
import { DEPRECATION_SENTINEL } from "../vbrief-build/constants.js";
|
|
7
7
|
export { DEPRECATION_SENTINEL as DEPRECATED_REDIRECT_SENTINEL };
|
|
8
8
|
const DEPRECATION_REDIRECT_PURPOSE = "<!-- Purpose: deprecation redirect -->";
|
|
@@ -27,15 +27,10 @@ export function isDeprecationRedirect(content) {
|
|
|
27
27
|
}
|
|
28
28
|
/** Full-spec generated export (layout-resolved specification artifact source line). */
|
|
29
29
|
export function isGeneratedSpecificationExport(projectRoot, content) {
|
|
30
|
-
if (!content.includes(GENERATED_SPEC_PURPOSE)
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
return existsSync(resolveSpecArtifactPath(projectRoot));
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
30
|
+
if (!content.includes(GENERATED_SPEC_PURPOSE)) {
|
|
37
31
|
return false;
|
|
38
32
|
}
|
|
33
|
+
return contentHasResolvedSpecSource(projectRoot, content);
|
|
39
34
|
}
|
|
40
35
|
/** Return true for a fully current generated spec export (full-spec or greenfield). */
|
|
41
36
|
export function isCurrentGeneratedSpecification(projectRoot, content) {
|
|
@@ -21,6 +21,24 @@ export interface ClauseWalkResult {
|
|
|
21
21
|
readonly artifact_path: string | null;
|
|
22
22
|
readonly outcome: ClauseOutcome;
|
|
23
23
|
readonly detail: string;
|
|
24
|
+
/**
|
|
25
|
+
* True when the walk had an oracle for this clause — a path the brief declared
|
|
26
|
+
* on `plan.metadata.swarm.file_scope`. An unbound or undeclared clause can only
|
|
27
|
+
* ever come back `unverifiable`, so it carries no weight either way (#3835).
|
|
28
|
+
*/
|
|
29
|
+
readonly adjudicable: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Read-scope for the walk. Empty means nothing is read (#3835). */
|
|
32
|
+
export interface ClauseWalkOptions {
|
|
33
|
+
/**
|
|
34
|
+
* The brief's declared artifact surface: `plan.metadata.swarm.file_scope`,
|
|
35
|
+
* which carries the #3145 approved-scope digest and `humanApproval` gate.
|
|
36
|
+
*
|
|
37
|
+
* Required rather than optional, and fail-closed when empty: the walk reads
|
|
38
|
+
* files, and a caller that forgets to pass a scope must read nothing rather
|
|
39
|
+
* than fall back to whatever path a clause happens to carry.
|
|
40
|
+
*/
|
|
41
|
+
readonly declaredScope: readonly string[];
|
|
24
42
|
}
|
|
25
43
|
export interface ClauseWalkReport {
|
|
26
44
|
readonly clauses: readonly ClauseWalkResult[];
|
|
@@ -30,8 +48,24 @@ export interface ClauseWalkReport {
|
|
|
30
48
|
readonly ok: boolean;
|
|
31
49
|
readonly message: string;
|
|
32
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Acceptance lines declared on `plan.items` (#3826).
|
|
53
|
+
*
|
|
54
|
+
* Prefers `item.narrative.Acceptance`, then `item.title` — criteria routinely live
|
|
55
|
+
* in the title with an empty `narrative`, which is how a declared acceptance
|
|
56
|
+
* surface stayed invisible to derivation on #3794 and #3819.
|
|
57
|
+
*/
|
|
58
|
+
export declare function collectPlanItemAcceptanceSurface(plan: Record<string, unknown>): string[];
|
|
59
|
+
export interface ClauseDerivationSources {
|
|
60
|
+
/**
|
|
61
|
+
* Declared acceptance lines from `plan.items`. When non-empty this IS the
|
|
62
|
+
* derived clause set; the statement extractors below are the path for a brief
|
|
63
|
+
* that declares no items (#3826).
|
|
64
|
+
*/
|
|
65
|
+
readonly itemSurface?: readonly string[];
|
|
66
|
+
}
|
|
33
67
|
/** Numbered independently testable clauses from the task statement (#3323). */
|
|
34
|
-
export declare function deriveAcceptanceClauses(taskStatement: string): AcceptanceClause[];
|
|
68
|
+
export declare function deriveAcceptanceClauses(taskStatement: string, sources?: ClauseDerivationSources): AcceptanceClause[];
|
|
35
69
|
export declare function readAcceptanceClauses(acceptance: unknown): AcceptanceClause[];
|
|
36
70
|
export declare function serializeAcceptanceClauses(clauses: readonly AcceptanceClause[]): Record<string, unknown>[];
|
|
37
71
|
/**
|
|
@@ -43,7 +77,33 @@ export declare function stampDerivedClausesOnAcceptance(plan: Record<string, unk
|
|
|
43
77
|
readonly clauses: readonly AcceptanceClause[];
|
|
44
78
|
};
|
|
45
79
|
export declare function isScratchArtifactPath(artifactPath: string): boolean;
|
|
46
|
-
|
|
80
|
+
/**
|
|
81
|
+
* The declared artifact surface for a brief: `plan.metadata.swarm.file_scope`.
|
|
82
|
+
*
|
|
83
|
+
* This is the only surface the walk reads from (#3835). It sits inside the
|
|
84
|
+
* xBRIEF, so a GitHub commenter cannot write it, and it is already gated by the
|
|
85
|
+
* #3145 approved-scope digest and `humanApproval` stamp.
|
|
86
|
+
*/
|
|
87
|
+
export declare function readDeclaredArtifactScope(plan: unknown): string[];
|
|
88
|
+
/** True when the clause binding is a declared entry or sits under a declared directory. */
|
|
89
|
+
export declare function isDeclaredArtifactPath(artifactPath: string, declaredScope: readonly string[]): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Clauses the walk had an oracle for — bound to a declared artifact path.
|
|
92
|
+
*
|
|
93
|
+
* A clause with no oracle can only ever be `unverifiable`, so requiring a positive
|
|
94
|
+
* `verified` from a set of them is unsatisfiable by correct work rather than a
|
|
95
|
+
* quality bar (#3826).
|
|
96
|
+
*/
|
|
97
|
+
export declare function countAdjudicableClauses(rows: readonly ClauseWalkResult[]): number;
|
|
98
|
+
/**
|
|
99
|
+
* Adjudicable clauses the walk did not verify.
|
|
100
|
+
*
|
|
101
|
+
* #3826 made `verified > 0` a *set* predicate excused by an empty oracle set, so
|
|
102
|
+
* one bound-and-verified clause re-armed the whole set and covered siblings with
|
|
103
|
+
* their own unmet oracle. Counting per clause is what removes that seam (#3835).
|
|
104
|
+
*/
|
|
105
|
+
export declare function countUnverifiedAdjudicableClauses(rows: readonly ClauseWalkResult[]): number;
|
|
106
|
+
export declare function walkAcceptanceClauses(clauses: readonly AcceptanceClause[], projectRoot: string, options: ClauseWalkOptions): ClauseWalkReport;
|
|
47
107
|
/** Done reports lead with failed/unverifiable; unverifiable is never dropped. */
|
|
48
108
|
export declare function formatClauseWalkMessage(report: Omit<ClauseWalkReport, "message"> & {
|
|
49
109
|
readonly message?: string;
|
|
@@ -133,14 +133,44 @@ function collectPathBearingLines(text) {
|
|
|
133
133
|
}
|
|
134
134
|
return items;
|
|
135
135
|
}
|
|
136
|
-
/**
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Acceptance lines declared on `plan.items` (#3826).
|
|
138
|
+
*
|
|
139
|
+
* Prefers `item.narrative.Acceptance`, then `item.title` — criteria routinely live
|
|
140
|
+
* in the title with an empty `narrative`, which is how a declared acceptance
|
|
141
|
+
* surface stayed invisible to derivation on #3794 and #3819.
|
|
142
|
+
*/
|
|
143
|
+
export function collectPlanItemAcceptanceSurface(plan) {
|
|
144
|
+
if (!Array.isArray(plan.items)) {
|
|
140
145
|
return [];
|
|
141
146
|
}
|
|
142
|
-
const
|
|
147
|
+
const lines = [];
|
|
148
|
+
const seen = new Set();
|
|
149
|
+
for (const entry of plan.items) {
|
|
150
|
+
const item = asRecord(entry);
|
|
151
|
+
if (item === null) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const narrative = asRecord(item.narrative);
|
|
155
|
+
const declared = narrative === null ? undefined : narrative.Acceptance;
|
|
156
|
+
const source = isNonEmptyString(declared) ? declared : item.title;
|
|
157
|
+
if (!isNonEmptyString(source)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const line = normalizeClauseText(source.replace(/\*\*/g, ""));
|
|
161
|
+
const key = line.toLowerCase();
|
|
162
|
+
if (line.length === 0 || isMetaClause(line) || seen.has(key)) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
seen.add(key);
|
|
166
|
+
lines.push(line);
|
|
167
|
+
}
|
|
168
|
+
return lines;
|
|
169
|
+
}
|
|
170
|
+
/** Acceptance lines the statement itself declares, in extractor precedence order. */
|
|
171
|
+
function collectStatementSurface(text) {
|
|
143
172
|
const raw = [];
|
|
173
|
+
const acHeading = findAcHeading(text);
|
|
144
174
|
if (acHeading !== null) {
|
|
145
175
|
raw.push(...parseListItems(sliceAcSection(text, acHeading))
|
|
146
176
|
.map((item) => normalizeClauseText(item.title.replace(/\*\*/g, "")))
|
|
@@ -151,6 +181,22 @@ export function deriveAcceptanceClauses(taskStatement) {
|
|
|
151
181
|
if (raw.length === 0) {
|
|
152
182
|
raw.push(...collectPathBearingLines(text));
|
|
153
183
|
}
|
|
184
|
+
return raw;
|
|
185
|
+
}
|
|
186
|
+
/** Numbered independently testable clauses from the task statement (#3323). */
|
|
187
|
+
export function deriveAcceptanceClauses(taskStatement, sources = {}) {
|
|
188
|
+
const text = taskStatement.trim();
|
|
189
|
+
const itemSurface = (sources.itemSurface ?? [])
|
|
190
|
+
.map((line) => normalizeClauseText(line))
|
|
191
|
+
.filter((line) => line.length > 0 && !isMetaClause(line));
|
|
192
|
+
// #3826: `plan.items` is a declared, body-scoped acceptance surface, while the
|
|
193
|
+
// statement carries the whole untrusted issue comment thread. Preferring the
|
|
194
|
+
// declared surface is what keeps an acceptance-shaped heading buried in that
|
|
195
|
+
// thread from becoming the gate — the #3794 and #3819 mechanism.
|
|
196
|
+
let raw = itemSurface;
|
|
197
|
+
if (raw.length === 0) {
|
|
198
|
+
raw = text.length > 0 ? collectStatementSurface(text) : [];
|
|
199
|
+
}
|
|
154
200
|
const seen = new Set();
|
|
155
201
|
const clauses = [];
|
|
156
202
|
for (const line of raw) {
|
|
@@ -163,28 +209,20 @@ export function deriveAcceptanceClauses(taskStatement) {
|
|
|
163
209
|
}
|
|
164
210
|
return clauses;
|
|
165
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Clause text is untrusted: the statement is the issue body plus its whole
|
|
214
|
+
* comment thread, and anyone can comment on a public issue. Lifting a path out
|
|
215
|
+
* of it chose both the file `walkOne` read and the needle it matched, so a
|
|
216
|
+
* third-party comment could ask the gate a question about any in-root file and
|
|
217
|
+
* read the answer off the report (#3835).
|
|
218
|
+
*
|
|
219
|
+
* Derivation therefore binds no path at all. `walkOne` binds only what the brief
|
|
220
|
+
* declares on `plan.metadata.swarm.file_scope`. Measured across the six live
|
|
221
|
+
* briefs at filing, prose extraction bound two paths and verified zero clauses,
|
|
222
|
+
* so this costs no verification capability.
|
|
223
|
+
*/
|
|
166
224
|
function buildClause(id, text) {
|
|
167
|
-
|
|
168
|
-
if (paths.length <= 1) {
|
|
169
|
-
return {
|
|
170
|
-
id,
|
|
171
|
-
text,
|
|
172
|
-
artifact_path: paths[0] ?? null,
|
|
173
|
-
ambiguous: false,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
const readings = paths.map((artifact_path) => ({
|
|
177
|
-
text: `${text} [reading: ${artifact_path}]`,
|
|
178
|
-
artifact_path,
|
|
179
|
-
}));
|
|
180
|
-
return {
|
|
181
|
-
id,
|
|
182
|
-
text,
|
|
183
|
-
artifact_path: paths[0] ?? null,
|
|
184
|
-
ambiguous: true,
|
|
185
|
-
readings,
|
|
186
|
-
chosen_reading: 0,
|
|
187
|
-
};
|
|
225
|
+
return { id, text, artifact_path: null, ambiguous: false };
|
|
188
226
|
}
|
|
189
227
|
export function readAcceptanceClauses(acceptance) {
|
|
190
228
|
const rec = asRecord(acceptance);
|
|
@@ -273,7 +311,9 @@ export function stampDerivedClausesOnAcceptance(plan, taskStatement) {
|
|
|
273
311
|
if (Array.isArray(commands) && commands.length > 0) {
|
|
274
312
|
return { plan, clauses: [] };
|
|
275
313
|
}
|
|
276
|
-
const clauses = deriveAcceptanceClauses(taskStatement
|
|
314
|
+
const clauses = deriveAcceptanceClauses(taskStatement, {
|
|
315
|
+
itemSurface: collectPlanItemAcceptanceSurface(plan),
|
|
316
|
+
});
|
|
277
317
|
if (clauses.length === 0) {
|
|
278
318
|
return { plan, clauses: [] };
|
|
279
319
|
}
|
|
@@ -295,6 +335,57 @@ export function isScratchArtifactPath(artifactPath) {
|
|
|
295
335
|
const unified = artifactPath.replace(/\\/g, "/").toLowerCase();
|
|
296
336
|
return unified.split("/").some((seg) => SCRATCH_SEGMENTS.has(seg));
|
|
297
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Repo-relative comparison form: forward slashes, no `./` prefix, no trailing slash.
|
|
340
|
+
*
|
|
341
|
+
* Segment-split rather than regex-replaced: the inputs include clause text a
|
|
342
|
+
* commenter wrote, and the anchored slash-run patterns this replaced backtrack
|
|
343
|
+
* quadratically on a long run of separators (`js/polynomial-redos`).
|
|
344
|
+
*/
|
|
345
|
+
function normalizeScopePath(value) {
|
|
346
|
+
const unified = value.trim().split("\\").join("/");
|
|
347
|
+
const rooted = unified.startsWith("/") ? "/" : "";
|
|
348
|
+
const segments = unified.split("/").filter((segment) => segment.length > 0);
|
|
349
|
+
if (rooted.length === 0 && segments[0] === ".") {
|
|
350
|
+
segments.shift();
|
|
351
|
+
}
|
|
352
|
+
return rooted + segments.join("/");
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* The declared artifact surface for a brief: `plan.metadata.swarm.file_scope`.
|
|
356
|
+
*
|
|
357
|
+
* This is the only surface the walk reads from (#3835). It sits inside the
|
|
358
|
+
* xBRIEF, so a GitHub commenter cannot write it, and it is already gated by the
|
|
359
|
+
* #3145 approved-scope digest and `humanApproval` stamp.
|
|
360
|
+
*/
|
|
361
|
+
export function readDeclaredArtifactScope(plan) {
|
|
362
|
+
const swarm = asRecord(asRecord(asRecord(plan)?.metadata)?.swarm);
|
|
363
|
+
if (swarm === null || !Array.isArray(swarm.file_scope)) {
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
const declared = new Set();
|
|
367
|
+
for (const entry of swarm.file_scope) {
|
|
368
|
+
if (!isNonEmptyString(entry)) {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
const normalized = normalizeScopePath(entry);
|
|
372
|
+
if (normalized.length > 0) {
|
|
373
|
+
declared.add(normalized);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return [...declared];
|
|
377
|
+
}
|
|
378
|
+
/** True when the clause binding is a declared entry or sits under a declared directory. */
|
|
379
|
+
export function isDeclaredArtifactPath(artifactPath, declaredScope) {
|
|
380
|
+
const candidate = normalizeScopePath(artifactPath);
|
|
381
|
+
if (candidate.length === 0 || candidate === ".." || candidate.startsWith("../")) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
return declaredScope.some((raw) => {
|
|
385
|
+
const entry = normalizeScopePath(raw);
|
|
386
|
+
return entry.length > 0 && (candidate === entry || candidate.startsWith(`${entry}/`));
|
|
387
|
+
});
|
|
388
|
+
}
|
|
298
389
|
function isContained(root, child) {
|
|
299
390
|
const rel = relative(resolve(root), resolve(child));
|
|
300
391
|
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
@@ -318,7 +409,7 @@ function extractExpectedTokens(clause) {
|
|
|
318
409
|
}
|
|
319
410
|
return tokens;
|
|
320
411
|
}
|
|
321
|
-
function walkOne(clause, projectRoot) {
|
|
412
|
+
function walkOne(clause, projectRoot, declaredScope) {
|
|
322
413
|
const artifactPath = clause.artifact_path;
|
|
323
414
|
if (artifactPath === null || artifactPath.trim().length === 0) {
|
|
324
415
|
return {
|
|
@@ -327,73 +418,64 @@ function walkOne(clause, projectRoot) {
|
|
|
327
418
|
artifact_path: artifactPath,
|
|
328
419
|
outcome: "unverifiable",
|
|
329
420
|
detail: "no artifact path bound",
|
|
421
|
+
adjudicable: false,
|
|
330
422
|
};
|
|
331
423
|
}
|
|
332
|
-
|
|
424
|
+
// #3835: every filesystem touch below this line — existence, stat, and the
|
|
425
|
+
// token read — is gated here. A path the brief did not declare is refused
|
|
426
|
+
// before the walk learns anything about it, and the refusal detail is a
|
|
427
|
+
// function of the path alone, so a rejected clause reports the same thing
|
|
428
|
+
// whatever needle it carries. Filtering the shape of the path upstream was
|
|
429
|
+
// measured to narrow this by zero; this is the line that closes it.
|
|
430
|
+
if (!isDeclaredArtifactPath(artifactPath, declaredScope)) {
|
|
333
431
|
return {
|
|
334
432
|
id: clause.id,
|
|
335
433
|
text: clause.text,
|
|
336
434
|
artifact_path: artifactPath,
|
|
337
|
-
outcome: "
|
|
338
|
-
detail:
|
|
435
|
+
outcome: "unverifiable",
|
|
436
|
+
detail: `artifact path is not declared on plan.metadata.swarm.file_scope, so nothing ` +
|
|
437
|
+
`was read: ${artifactPath} (#3835)`,
|
|
438
|
+
adjudicable: false,
|
|
339
439
|
};
|
|
340
440
|
}
|
|
441
|
+
// Past the declared-scope gate the walk has an oracle, so every outcome below
|
|
442
|
+
// counts toward the `ok` predicate.
|
|
443
|
+
const bound = (outcome, detail) => ({
|
|
444
|
+
id: clause.id,
|
|
445
|
+
text: clause.text,
|
|
446
|
+
artifact_path: artifactPath,
|
|
447
|
+
outcome,
|
|
448
|
+
detail,
|
|
449
|
+
adjudicable: true,
|
|
450
|
+
});
|
|
451
|
+
if (isScratchArtifactPath(artifactPath)) {
|
|
452
|
+
return bound("failed", "artifact path is a buffer/scratch copy, not the shipped path");
|
|
453
|
+
}
|
|
341
454
|
const abs = resolve(projectRoot, artifactPath);
|
|
342
455
|
if (!isContained(projectRoot, abs)) {
|
|
343
|
-
return
|
|
344
|
-
id: clause.id,
|
|
345
|
-
text: clause.text,
|
|
346
|
-
artifact_path: artifactPath,
|
|
347
|
-
outcome: "failed",
|
|
348
|
-
detail: "artifact path escaped the project root",
|
|
349
|
-
};
|
|
456
|
+
return bound("failed", "artifact path escaped the project root");
|
|
350
457
|
}
|
|
351
458
|
if (!existsSync(abs)) {
|
|
352
459
|
if (NEGATED_EXISTENCE.test(clause.text)) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
};
|
|
460
|
+
// #3826: absence is not evidence. The negation phrase is matched against the
|
|
461
|
+
// whole clause text, so on a derived clause it routinely refers to something
|
|
462
|
+
// other than the bound path — a bare `git.ts` in analysis prose passed here
|
|
463
|
+
// and was the sole `verified` row propping up the `ok` predicate on #3794.
|
|
464
|
+
return bound("unverifiable", `artifact absent at ${artifactPath}; a prose negation is not evidence ` +
|
|
465
|
+
`the clause requires this path to be absent (#3826)`);
|
|
360
466
|
}
|
|
361
|
-
return {
|
|
362
|
-
id: clause.id,
|
|
363
|
-
text: clause.text,
|
|
364
|
-
artifact_path: artifactPath,
|
|
365
|
-
outcome: "failed",
|
|
366
|
-
detail: `artifact missing at stated path ${artifactPath}`,
|
|
367
|
-
};
|
|
467
|
+
return bound("failed", `artifact missing at stated path ${artifactPath}`);
|
|
368
468
|
}
|
|
369
469
|
try {
|
|
370
470
|
if (!statSync(abs).isFile()) {
|
|
371
|
-
return {
|
|
372
|
-
id: clause.id,
|
|
373
|
-
text: clause.text,
|
|
374
|
-
artifact_path: artifactPath,
|
|
375
|
-
outcome: "failed",
|
|
376
|
-
detail: `stated path is not a shipped file: ${artifactPath}`,
|
|
377
|
-
};
|
|
471
|
+
return bound("failed", `stated path is not a shipped file: ${artifactPath}`);
|
|
378
472
|
}
|
|
379
473
|
}
|
|
380
474
|
catch {
|
|
381
|
-
return {
|
|
382
|
-
id: clause.id,
|
|
383
|
-
text: clause.text,
|
|
384
|
-
artifact_path: artifactPath,
|
|
385
|
-
outcome: "failed",
|
|
386
|
-
detail: `artifact unreadable at stated path ${artifactPath}`,
|
|
387
|
-
};
|
|
475
|
+
return bound("failed", `artifact unreadable at stated path ${artifactPath}`);
|
|
388
476
|
}
|
|
389
477
|
if (NEGATED_EXISTENCE.test(clause.text)) {
|
|
390
|
-
return {
|
|
391
|
-
id: clause.id,
|
|
392
|
-
text: clause.text,
|
|
393
|
-
artifact_path: artifactPath,
|
|
394
|
-
outcome: "failed",
|
|
395
|
-
detail: `artifact exists at ${artifactPath} but the clause requires absence`,
|
|
396
|
-
};
|
|
478
|
+
return bound("failed", `artifact exists at ${artifactPath} but the clause requires absence`);
|
|
397
479
|
}
|
|
398
480
|
const expected = extractExpectedTokens(clause);
|
|
399
481
|
if (expected.length > 0) {
|
|
@@ -402,55 +484,45 @@ function walkOne(clause, projectRoot) {
|
|
|
402
484
|
body = readFileSync(abs, "utf8");
|
|
403
485
|
}
|
|
404
486
|
catch {
|
|
405
|
-
return {
|
|
406
|
-
id: clause.id,
|
|
407
|
-
text: clause.text,
|
|
408
|
-
artifact_path: artifactPath,
|
|
409
|
-
outcome: "failed",
|
|
410
|
-
detail: `artifact unreadable at stated path ${artifactPath}`,
|
|
411
|
-
};
|
|
487
|
+
return bound("failed", `artifact unreadable at stated path ${artifactPath}`);
|
|
412
488
|
}
|
|
413
489
|
const missing = expected.filter((token) => !body.includes(token));
|
|
414
490
|
if (missing.length > 0) {
|
|
415
|
-
return {
|
|
416
|
-
id: clause.id,
|
|
417
|
-
text: clause.text,
|
|
418
|
-
artifact_path: artifactPath,
|
|
419
|
-
outcome: "failed",
|
|
420
|
-
detail: `expected token(s) missing from ${artifactPath}: ${missing.join(", ")}`,
|
|
421
|
-
};
|
|
491
|
+
return bound("failed", `expected token(s) missing from ${artifactPath}: ${missing.join(", ")}`);
|
|
422
492
|
}
|
|
423
|
-
return {
|
|
424
|
-
id: clause.id,
|
|
425
|
-
text: clause.text,
|
|
426
|
-
artifact_path: artifactPath,
|
|
427
|
-
outcome: "verified",
|
|
428
|
-
detail: `tokens present in shipped artifact ${artifactPath}`,
|
|
429
|
-
};
|
|
493
|
+
return bound("verified", `tokens present in shipped artifact ${artifactPath}`);
|
|
430
494
|
}
|
|
431
495
|
if (EXISTENCE_CLAIM.test(clause.text)) {
|
|
432
|
-
return {
|
|
433
|
-
id: clause.id,
|
|
434
|
-
text: clause.text,
|
|
435
|
-
artifact_path: artifactPath,
|
|
436
|
-
outcome: "verified",
|
|
437
|
-
detail: `shipped artifact exists at ${artifactPath}`,
|
|
438
|
-
};
|
|
496
|
+
return bound("verified", `shipped artifact exists at ${artifactPath}`);
|
|
439
497
|
}
|
|
440
|
-
return {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
498
|
+
return bound("unverifiable", `cannot evaluate behavioral claim against shipped artifact ${artifactPath}`);
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Clauses the walk had an oracle for — bound to a declared artifact path.
|
|
502
|
+
*
|
|
503
|
+
* A clause with no oracle can only ever be `unverifiable`, so requiring a positive
|
|
504
|
+
* `verified` from a set of them is unsatisfiable by correct work rather than a
|
|
505
|
+
* quality bar (#3826).
|
|
506
|
+
*/
|
|
507
|
+
export function countAdjudicableClauses(rows) {
|
|
508
|
+
return rows.filter((row) => row.adjudicable).length;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Adjudicable clauses the walk did not verify.
|
|
512
|
+
*
|
|
513
|
+
* #3826 made `verified > 0` a *set* predicate excused by an empty oracle set, so
|
|
514
|
+
* one bound-and-verified clause re-armed the whole set and covered siblings with
|
|
515
|
+
* their own unmet oracle. Counting per clause is what removes that seam (#3835).
|
|
516
|
+
*/
|
|
517
|
+
export function countUnverifiedAdjudicableClauses(rows) {
|
|
518
|
+
return rows.filter((row) => row.adjudicable && row.outcome !== "verified").length;
|
|
447
519
|
}
|
|
448
|
-
export function walkAcceptanceClauses(clauses, projectRoot) {
|
|
449
|
-
const walked = clauses.map((clause) => walkOne(clause, projectRoot));
|
|
520
|
+
export function walkAcceptanceClauses(clauses, projectRoot, options) {
|
|
521
|
+
const walked = clauses.map((clause) => walkOne(clause, projectRoot, options.declaredScope));
|
|
450
522
|
const failed = walked.filter((row) => row.outcome === "failed");
|
|
451
523
|
const unverifiable = walked.filter((row) => row.outcome === "unverifiable");
|
|
452
524
|
const verified = walked.filter((row) => row.outcome === "verified");
|
|
453
|
-
const ok = failed.length === 0 && (
|
|
525
|
+
const ok = failed.length === 0 && countUnverifiedAdjudicableClauses(walked) === 0;
|
|
454
526
|
return {
|
|
455
527
|
clauses: walked,
|
|
456
528
|
failed,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Extends #3156: a red product verification may not be self-adjudicated
|
|
5
5
|
* by editing the comparison. Deterministic surface is the flagged event.
|
|
6
6
|
*/
|
|
7
|
-
export { type AcceptanceClause, type AcceptanceClauseReading, type ClauseOutcome, type ClauseWalkReport, type ClauseWalkResult, deriveAcceptanceClauses, formatClauseWalkMessage, isScratchArtifactPath, readAcceptanceClauses, serializeAcceptanceClauses, stampDerivedClausesOnAcceptance, walkAcceptanceClauses, } from "./clauses.js";
|
|
7
|
+
export { type AcceptanceClause, type AcceptanceClauseReading, type ClauseDerivationSources, type ClauseOutcome, type ClauseWalkOptions, type ClauseWalkReport, type ClauseWalkResult, collectPlanItemAcceptanceSurface, countAdjudicableClauses, countUnverifiedAdjudicableClauses, deriveAcceptanceClauses, formatClauseWalkMessage, isDeclaredArtifactPath, isScratchArtifactPath, readAcceptanceClauses, readDeclaredArtifactScope, serializeAcceptanceClauses, stampDerivedClausesOnAcceptance, walkAcceptanceClauses, } from "./clauses.js";
|
|
8
8
|
export { type EvaluateProductOracleIntegrityOptions, emitVerifyAcAttempts, evaluateProductOracleIntegrity, mergeOracleVerdict, methodFingerprintForWalk, type OracleIntegrityResultFields, type ProductOracleIntegrityVerdict, VERIFY_AC_CHECK_ID_PREFIX, verifyAcCheckId, } from "./evaluate.js";
|
|
9
9
|
export { commandCountFromFingerprint, type FlaggedMethodChangePass, flagPassAfterFailFromJsonl, flagPassAfterFailWithMethodChange, readVerificationAttempts, unresolvedMethodChangePasses, type VerificationAttempt, } from "./flag.js";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/verify-ac/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Extends #3156: a red product verification may not be self-adjudicated
|
|
5
5
|
* by editing the comparison. Deterministic surface is the flagged event.
|
|
6
6
|
*/
|
|
7
|
-
export { deriveAcceptanceClauses, formatClauseWalkMessage, isScratchArtifactPath, readAcceptanceClauses, serializeAcceptanceClauses, stampDerivedClausesOnAcceptance, walkAcceptanceClauses, } from "./clauses.js";
|
|
7
|
+
export { collectPlanItemAcceptanceSurface, countAdjudicableClauses, countUnverifiedAdjudicableClauses, deriveAcceptanceClauses, formatClauseWalkMessage, isDeclaredArtifactPath, isScratchArtifactPath, readAcceptanceClauses, readDeclaredArtifactScope, serializeAcceptanceClauses, stampDerivedClausesOnAcceptance, walkAcceptanceClauses, } from "./clauses.js";
|
|
8
8
|
export { emitVerifyAcAttempts, evaluateProductOracleIntegrity, mergeOracleVerdict, methodFingerprintForWalk, VERIFY_AC_CHECK_ID_PREFIX, verifyAcCheckId, } from "./evaluate.js";
|
|
9
9
|
export { commandCountFromFingerprint, flagPassAfterFailFromJsonl, flagPassAfterFailWithMethodChange, readVerificationAttempts, unresolvedMethodChangePasses, } from "./flag.js";
|
|
10
10
|
//# sourceMappingURL=index.js.map
|