@deftai/directive-core 0.104.0 → 0.105.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/authz/classify.js +526 -42
- package/dist/check/cached-orchestrator.d.ts +1 -1
- package/dist/check/cached-orchestrator.js +2 -2
- package/dist/check/named-cause.d.ts +1 -1
- package/dist/check/named-cause.js +33 -3
- package/dist/codebase/default-extractor.d.ts +5 -0
- package/dist/codebase/default-extractor.js +7 -15
- package/dist/deposit/copy-tree.js +60 -0
- package/dist/deposit/python-free.js +26 -18
- package/dist/doctor/checks.d.ts +8 -0
- package/dist/doctor/checks.js +37 -25
- package/dist/doctor/doctor-state.d.ts +4 -0
- package/dist/doctor/doctor-state.js +7 -1
- package/dist/doctor/main.js +9 -19
- package/dist/doctor/types.d.ts +9 -0
- package/dist/fs/contained-write.d.ts +115 -1
- package/dist/fs/contained-write.js +241 -5
- package/dist/fs/mutation-ledger.d.ts +54 -0
- package/dist/fs/mutation-ledger.js +133 -0
- package/dist/fs/non-product-dirs.d.ts +79 -0
- package/dist/fs/non-product-dirs.js +96 -0
- package/dist/hooks/dispatcher.d.ts +3 -1
- package/dist/hooks/dispatcher.js +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/agent-hooks.js +17 -15
- package/dist/init-deposit/core-guard-pin-content.d.ts +7 -0
- package/dist/init-deposit/core-guard-pin-content.js +393 -0
- package/dist/init-deposit/gitignore.js +9 -0
- package/dist/init-deposit/hygiene.d.ts +47 -11
- package/dist/init-deposit/hygiene.js +172 -37
- package/dist/init-deposit/legacy-detect.js +6 -2
- package/dist/init-deposit/refresh.d.ts +21 -1
- package/dist/init-deposit/refresh.js +106 -9
- package/dist/init-deposit/scaffold.js +28 -279
- package/dist/init-deposit/slash-deposit.js +13 -7
- package/dist/init-deposit/xbrief-projections.d.ts +8 -1
- package/dist/init-deposit/xbrief-projections.js +24 -11
- package/dist/intake/clause-derivation.d.ts +38 -1
- package/dist/intake/clause-derivation.js +211 -9
- package/dist/intake/issue-ingest.d.ts +3 -1
- package/dist/intake/issue-ingest.js +35 -6
- package/dist/lifecycle/completed-tracked-on-delivery.d.ts +5 -0
- package/dist/lifecycle/completed-tracked-on-delivery.js +85 -18
- package/dist/literal-acceptance/capture.d.ts +10 -0
- package/dist/literal-acceptance/capture.js +224 -75
- package/dist/literal-acceptance/evaluate.d.ts +29 -4
- package/dist/literal-acceptance/evaluate.js +70 -2
- package/dist/literal-acceptance/index.d.ts +3 -3
- package/dist/literal-acceptance/index.js +3 -3
- package/dist/literal-acceptance/safety.d.ts +41 -0
- package/dist/literal-acceptance/safety.js +126 -2
- package/dist/literal-acceptance/types.d.ts +8 -0
- package/dist/orphan-active/evaluate.d.ts +7 -1
- package/dist/orphan-active/evaluate.js +102 -23
- package/dist/platform/platform-capabilities.js +2 -3
- package/dist/policy/base-branch.d.ts +37 -0
- package/dist/policy/base-branch.js +114 -0
- package/dist/policy/branch-sync.d.ts +80 -0
- package/dist/policy/branch-sync.js +211 -0
- package/dist/policy/ceremony-dial-escalation.js +1 -0
- package/dist/policy/ceremony-dial.js +4 -14
- package/dist/policy/delivery-branch.d.ts +5 -3
- package/dist/policy/delivery-branch.js +7 -3
- package/dist/policy/file-size-thresholds.d.ts +24 -0
- package/dist/policy/file-size-thresholds.js +23 -0
- package/dist/policy/forge-outage-retry.d.ts +47 -0
- package/dist/policy/forge-outage-retry.js +157 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.js +66 -7
- package/dist/policy/project-invariants.d.ts +50 -0
- package/dist/policy/project-invariants.js +205 -0
- package/dist/policy/sync-default.d.ts +129 -0
- package/dist/policy/sync-default.js +452 -0
- package/dist/policy/sync-max-files.d.ts +93 -0
- package/dist/policy/sync-max-files.js +192 -0
- package/dist/pr-monitor/absent-required.d.ts +11 -0
- package/dist/pr-monitor/absent-required.js +61 -0
- package/dist/pr-monitor/constants.d.ts +7 -0
- package/dist/pr-monitor/constants.js +7 -0
- package/dist/pr-monitor/index.d.ts +2 -1
- package/dist/pr-monitor/index.js +2 -1
- package/dist/pr-monitor/main.js +4 -0
- package/dist/pr-monitor/monitor.js +24 -1
- package/dist/pr-wait-mergeable/classify.js +6 -0
- package/dist/preflight/evaluate.d.ts +4 -0
- package/dist/preflight/evaluate.js +35 -1
- package/dist/preflight/index.d.ts +4 -0
- package/dist/preflight/index.js +2 -0
- package/dist/preflight/intended-placement.d.ts +62 -0
- package/dist/preflight/intended-placement.js +275 -0
- package/dist/preflight/project-invariants-gate.d.ts +29 -0
- package/dist/preflight/project-invariants-gate.js +82 -0
- package/dist/product-first-done-gate/acceptance-resolver.d.ts +128 -0
- package/dist/product-first-done-gate/acceptance-resolver.js +144 -0
- package/dist/product-first-done-gate/acceptance.d.ts +7 -4
- package/dist/product-first-done-gate/acceptance.js +79 -8
- package/dist/product-first-done-gate/empty-resolution.d.ts +4 -1
- package/dist/product-first-done-gate/empty-resolution.js +12 -1
- package/dist/product-first-done-gate/evaluate.d.ts +12 -0
- package/dist/product-first-done-gate/evaluate.js +254 -31
- package/dist/product-first-done-gate/index.d.ts +2 -0
- package/dist/product-first-done-gate/index.js +1 -0
- package/dist/release/build-dist.d.ts +101 -0
- package/dist/release/build-dist.js +428 -46
- package/dist/run-summary/emit.d.ts +16 -10
- package/dist/run-summary/emit.js +26 -15
- package/dist/run-summary/index.d.ts +3 -2
- package/dist/run-summary/index.js +2 -1
- package/dist/run-summary/session-id.d.ts +21 -0
- package/dist/run-summary/session-id.js +92 -0
- package/dist/run-summary/types.d.ts +29 -4
- package/dist/run-summary/types.js +1 -0
- package/dist/scope/acceptance-evidence.d.ts +19 -7
- package/dist/scope/acceptance-evidence.js +38 -11
- package/dist/scope/delivery-evidence.d.ts +3 -3
- package/dist/scope/delivery-evidence.js +22 -27
- package/dist/scope/index.d.ts +1 -0
- package/dist/scope/index.js +1 -0
- package/dist/scope/parent-lineage.js +7 -6
- package/dist/scope/project-invariant-coverage.d.ts +54 -0
- package/dist/scope/project-invariant-coverage.js +322 -0
- package/dist/scope/transition.js +1 -1
- package/dist/scope-provenance/compare-intent.d.ts +27 -0
- package/dist/scope-provenance/compare-intent.js +233 -0
- package/dist/scope-provenance/digest.d.ts +18 -1
- package/dist/scope-provenance/digest.js +16 -11
- package/dist/scope-provenance/evaluate.d.ts +5 -1
- package/dist/scope-provenance/evaluate.js +64 -4
- package/dist/scope-provenance/extract-intent.d.ts +43 -0
- package/dist/scope-provenance/extract-intent.js +262 -0
- package/dist/scope-provenance/index.d.ts +7 -1
- package/dist/scope-provenance/index.js +7 -1
- package/dist/scope-provenance/intent-digest.d.ts +12 -0
- package/dist/scope-provenance/intent-digest.js +33 -0
- package/dist/scope-provenance/intent-evaluate.d.ts +43 -0
- package/dist/scope-provenance/intent-evaluate.js +149 -0
- package/dist/scope-provenance/json-tokenizer.d.ts +19 -0
- package/dist/scope-provenance/json-tokenizer.js +225 -0
- package/dist/scope-provenance/known-machine.d.ts +38 -0
- package/dist/scope-provenance/known-machine.js +157 -0
- package/dist/scope-provenance/mint-artifacts.d.ts +102 -0
- package/dist/scope-provenance/mint-artifacts.js +425 -0
- package/dist/session/ac-pass-banking.d.ts +4 -36
- package/dist/session/ac-pass-banking.js +30 -77
- package/dist/session/ac-pass-reuse.d.ts +53 -0
- package/dist/session/ac-pass-reuse.js +95 -0
- package/dist/session/git.js +19 -4
- package/dist/session/index.d.ts +4 -0
- package/dist/session/index.js +4 -0
- package/dist/session/occupancy-stress-worker.d.ts +7 -0
- package/dist/session/occupancy-stress-worker.js +36 -0
- package/dist/session/occupancy.d.ts +97 -0
- package/dist/session/occupancy.js +422 -0
- package/dist/session/openclaw-soft-rebind-deposit.js +6 -6
- package/dist/session/product-state-hash.d.ts +26 -0
- package/dist/session/product-state-hash.js +683 -0
- package/dist/session/session-ready.d.ts +2 -0
- package/dist/session/session-ready.js +52 -30
- package/dist/session/session-start.d.ts +7 -0
- package/dist/session/session-start.js +71 -7
- package/dist/session/verify-ac-session-cache.d.ts +42 -0
- package/dist/session/verify-ac-session-cache.js +126 -0
- package/dist/session/verify-session-ritual.d.ts +5 -0
- package/dist/session/verify-session-ritual.js +9 -0
- package/dist/slash/openclaw-deposit.js +13 -9
- package/dist/slice/constants.d.ts +2 -2
- package/dist/slice/constants.js +2 -2
- package/dist/slice/existing.js +9 -3
- package/dist/slice/lock.d.ts +16 -1
- package/dist/slice/lock.js +137 -11
- package/dist/story-ready/evaluate.d.ts +2 -0
- package/dist/story-ready/evaluate.js +13 -0
- package/dist/swarm/complete-cohort.d.ts +3 -0
- package/dist/swarm/complete-cohort.js +59 -11
- package/dist/swarm/finalize-cohort.js +33 -2
- package/dist/swarm/launch.d.ts +22 -0
- package/dist/swarm/launch.js +155 -0
- package/dist/swarm/routing-set-cli.d.ts +11 -1
- package/dist/swarm/routing-set-cli.js +13 -3
- package/dist/swarm/routing-verify.d.ts +12 -0
- package/dist/swarm/routing-verify.js +59 -20
- package/dist/swarm/routing.d.ts +14 -0
- package/dist/swarm/routing.js +53 -3
- package/dist/telemetry-coverage/fake-trial.js +10 -0
- package/dist/telemetry-coverage/kinds.js +2 -0
- package/dist/triage/actions/index.js +4 -1
- package/dist/ts-check-lane/index.d.ts +3 -0
- package/dist/ts-check-lane/index.js +2 -0
- package/dist/ts-check-lane/progress-reporter.d.ts +17 -0
- package/dist/ts-check-lane/progress-reporter.js +38 -0
- package/dist/ts-check-lane/progress.d.ts +32 -0
- package/dist/ts-check-lane/progress.js +57 -0
- package/dist/ts-check-lane/run-lane.d.ts +3 -1
- package/dist/ts-check-lane/run-lane.js +8 -6
- package/dist/validate-content/validate-links.d.ts +8 -0
- package/dist/validate-content/validate-links.js +9 -15
- package/dist/value/feedback-file.js +12 -2
- package/dist/vbrief-build/index.d.ts +1 -0
- package/dist/vbrief-build/index.js +1 -0
- package/dist/vbrief-build/project-invariants-io.d.ts +16 -0
- package/dist/vbrief-build/project-invariants-io.js +41 -0
- package/dist/vbrief-reconcile/graph.js +18 -1
- package/dist/vbrief-reconcile/index.d.ts +1 -1
- package/dist/vbrief-reconcile/index.js +1 -1
- package/dist/vbrief-reconcile/types.d.ts +13 -0
- package/dist/vbrief-reconcile/umbrellas.d.ts +14 -0
- package/dist/vbrief-reconcile/umbrellas.js +261 -26
- package/dist/vbrief-validate/index.d.ts +1 -1
- package/dist/vbrief-validate/index.js +1 -1
- package/dist/vbrief-validate/plan-hooks.d.ts +4 -0
- package/dist/vbrief-validate/plan-hooks.js +68 -0
- package/dist/verify-ac/evaluate.d.ts +7 -1
- package/dist/verify-ac/evaluate.js +34 -26
- package/dist/verify-ac/flag.d.ts +4 -0
- package/dist/verify-ac/flag.js +16 -0
- package/dist/verify-ac/index.d.ts +2 -2
- package/dist/verify-ac/index.js +2 -2
- package/dist/verify-source/contained-writes.js +2 -0
- package/dist/verify-source/verify-stubs.d.ts +15 -1
- package/dist/verify-source/verify-stubs.js +20 -16
- package/dist/vitest-runner/win32-coverage-tmp-setup.d.ts +5 -6
- package/dist/vitest-runner/win32-coverage-tmp-setup.js +5 -6
- package/dist/xbrief-migrate/migrate-project.js +2 -5
- package/package.json +3 -3
|
@@ -10,19 +10,126 @@
|
|
|
10
10
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
11
|
import { basename, isAbsolute, relative, resolve } from "node:path";
|
|
12
12
|
import { emitAcceptanceStampFromPlan } from "../intake/clause-derivation.js";
|
|
13
|
-
import { evaluateLiteralAcceptanceFromPlan, runLiteralAcceptanceCommands, } from "../literal-acceptance/index.js";
|
|
13
|
+
import { appendLiteralAcceptanceAdvisory, evaluateLiteralAcceptanceFromPlan, isNoopRefusalReason, runLiteralAcceptanceCommands, stripLiteralAcceptanceAdvisory, } from "../literal-acceptance/index.js";
|
|
14
14
|
import { ENV_RUN_SUMMARY_PATH, RunSummaryEmitter, } from "../run-summary/index.js";
|
|
15
15
|
import { maybeBankOnAcPass } from "../session/ac-pass-banking.js";
|
|
16
|
+
import { resolveAcReuse, resolveScopeIdForAcReuse, snapshotFromReuseFields, } from "../session/ac-pass-reuse.js";
|
|
17
|
+
import { hashProductState } from "../session/product-state-hash.js";
|
|
18
|
+
import { resolveVerifyAcSessionId, writeVerifyAcSessionCache, } from "../session/verify-ac-session-cache.js";
|
|
16
19
|
import { formatClauseWalkMessage, walkAcceptanceClauses, } from "../verify-ac/clauses.js";
|
|
17
20
|
import { emitVerifyAcAttempts, evaluateProductOracleIntegrity, mergeOracleVerdict, } from "../verify-ac/evaluate.js";
|
|
18
21
|
import { readPlanAcceptance, validatePlanAcceptance } from "./acceptance.js";
|
|
19
|
-
import {
|
|
22
|
+
import { clauseWalkBlocks, formatAcceptanceVerdict, resolveAcceptanceVerdict, } from "./acceptance-resolver.js";
|
|
23
|
+
import { formatSoftEmptyMessage, formatTranscriptEmptyMessage, isEmptyAcResolution, projectHasSuiteFloor, } from "./empty-resolution.js";
|
|
20
24
|
function asRecord(value) {
|
|
21
25
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
22
26
|
return value;
|
|
23
27
|
}
|
|
24
28
|
return null;
|
|
25
29
|
}
|
|
30
|
+
function tryReuseVerifyAc(plan, acceptance, options, projectRoot) {
|
|
31
|
+
const mode = options.reuseMode ?? "auto";
|
|
32
|
+
if (mode === "never")
|
|
33
|
+
return null;
|
|
34
|
+
const reuse = resolveAcReuse({
|
|
35
|
+
projectRoot,
|
|
36
|
+
plan,
|
|
37
|
+
scopeId: options.bankScopeId,
|
|
38
|
+
sessionId: options.sessionId,
|
|
39
|
+
env: options.env,
|
|
40
|
+
productPaths: options.productPaths,
|
|
41
|
+
allowCache: mode === "auto",
|
|
42
|
+
allowBank: true,
|
|
43
|
+
});
|
|
44
|
+
if (reuse.kind === "miss")
|
|
45
|
+
return null;
|
|
46
|
+
if (reuse.kind === "cache") {
|
|
47
|
+
const snap = reuse.cache.snapshot;
|
|
48
|
+
const cachedAcceptance = readPlanAcceptance({ acceptance: snap.acceptance });
|
|
49
|
+
return {
|
|
50
|
+
ok: snap.ok,
|
|
51
|
+
code: snap.code,
|
|
52
|
+
message: options.quiet
|
|
53
|
+
? ""
|
|
54
|
+
: snap.message.includes("served_from=")
|
|
55
|
+
? snap.message
|
|
56
|
+
: `${snap.message} served_from=cache`,
|
|
57
|
+
commands: snap.commands,
|
|
58
|
+
runs: snap.runs,
|
|
59
|
+
rejected: snap.rejected,
|
|
60
|
+
sourceRung: acceptance.source_rung,
|
|
61
|
+
noneStated: acceptance.none_stated,
|
|
62
|
+
acceptance: cachedAcceptance.commands.length > 0 ? cachedAcceptance : acceptance,
|
|
63
|
+
resolution: "verified-pass",
|
|
64
|
+
resolvedCommandCount: snap.resolvedCommandCount,
|
|
65
|
+
servedFrom: "cache",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const commandCount = acceptance.commands.length;
|
|
69
|
+
if (commandCount === 0)
|
|
70
|
+
return null;
|
|
71
|
+
return {
|
|
72
|
+
ok: true,
|
|
73
|
+
code: 0,
|
|
74
|
+
message: options.quiet
|
|
75
|
+
? ""
|
|
76
|
+
: `verify:ac passed (#3284) served_from=bank [rung=${acceptance.source_rung}]`,
|
|
77
|
+
commands: acceptance.commands.map((c) => ({
|
|
78
|
+
command: c.command,
|
|
79
|
+
cwd: c.cwd ?? null,
|
|
80
|
+
expectedStdout: c.expectedStdout ?? null,
|
|
81
|
+
expectedExitCode: c.expectedExitCode ?? 0,
|
|
82
|
+
source: "explicit",
|
|
83
|
+
sourceSpan: "plan.acceptance.commands",
|
|
84
|
+
})),
|
|
85
|
+
runs: [],
|
|
86
|
+
sourceRung: acceptance.source_rung,
|
|
87
|
+
noneStated: acceptance.none_stated,
|
|
88
|
+
acceptance,
|
|
89
|
+
resolution: "verified-pass",
|
|
90
|
+
resolvedCommandCount: commandCount,
|
|
91
|
+
servedFrom: "bank",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function persistVerifyAcSessionCache(result, options, projectRoot, plan) {
|
|
95
|
+
if (!result.ok || result.resolution !== "verified-pass")
|
|
96
|
+
return;
|
|
97
|
+
const sessionId = resolveVerifyAcSessionId(options.env, options.sessionId);
|
|
98
|
+
const resolvedScope = resolveScopeIdForAcReuse(plan, options.bankScopeId);
|
|
99
|
+
if (sessionId === null || resolvedScope === null)
|
|
100
|
+
return;
|
|
101
|
+
const hashed = hashProductState({
|
|
102
|
+
projectRoot,
|
|
103
|
+
plan,
|
|
104
|
+
productPaths: options.productPaths,
|
|
105
|
+
});
|
|
106
|
+
if (!hashed.complete)
|
|
107
|
+
return;
|
|
108
|
+
try {
|
|
109
|
+
writeVerifyAcSessionCache({
|
|
110
|
+
projectRoot,
|
|
111
|
+
sessionId,
|
|
112
|
+
scopeId: resolvedScope,
|
|
113
|
+
productStateHash: hashed.digest,
|
|
114
|
+
snapshot: snapshotFromReuseFields({
|
|
115
|
+
ok: result.ok,
|
|
116
|
+
code: result.code === 2 ? 2 : result.code === 1 ? 1 : 0,
|
|
117
|
+
message: result.message,
|
|
118
|
+
commands: result.commands,
|
|
119
|
+
runs: result.runs,
|
|
120
|
+
rejected: result.rejected,
|
|
121
|
+
sourceRung: result.sourceRung,
|
|
122
|
+
noneStated: result.noneStated,
|
|
123
|
+
acceptance: result.acceptance,
|
|
124
|
+
resolution: result.resolution,
|
|
125
|
+
resolvedCommandCount: result.resolvedCommandCount,
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// fail-open: missing cache must not fail a green run
|
|
131
|
+
}
|
|
132
|
+
}
|
|
26
133
|
/**
|
|
27
134
|
* Evaluate product AC from an in-memory plan.
|
|
28
135
|
*/
|
|
@@ -31,26 +138,34 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
31
138
|
const optionsWithScope = {
|
|
32
139
|
...options,
|
|
33
140
|
oracleScopeKey: options.oracleScopeKey?.trim() || planId || null,
|
|
141
|
+
bankScopeId: options.bankScopeId?.trim() || planId || options.bankScopeId,
|
|
34
142
|
observedAcceptance: options.observedAcceptance !== undefined ? options.observedAcceptance : plan.acceptance,
|
|
35
143
|
};
|
|
36
144
|
const acceptance = readPlanAcceptance(plan);
|
|
37
145
|
const schemaErrors = validatePlanAcceptance(plan.acceptance ?? acceptance);
|
|
38
146
|
// Only hard-fail schema when an explicit plan.acceptance object exists.
|
|
39
147
|
if (plan.acceptance !== undefined && schemaErrors.length > 0) {
|
|
148
|
+
const noop = schemaErrors.some((error) => isNoopRefusalReason(error));
|
|
40
149
|
return applyOracle({
|
|
41
150
|
ok: false,
|
|
42
|
-
code: 2,
|
|
43
|
-
message:
|
|
151
|
+
code: noop ? 1 : 2,
|
|
152
|
+
message: noop
|
|
153
|
+
? `verify:ac rejected-noop (#3396): ${schemaErrors.join("; ")}`
|
|
154
|
+
: `verify:ac config error (#3284): ${schemaErrors.join("; ")}`,
|
|
44
155
|
commands: [],
|
|
45
156
|
runs: [],
|
|
46
157
|
sourceRung: acceptance.source_rung,
|
|
47
158
|
noneStated: acceptance.none_stated,
|
|
48
159
|
acceptance,
|
|
49
|
-
resolution: "config",
|
|
160
|
+
resolution: noop ? "rejected-noop" : "config",
|
|
50
161
|
resolvedCommandCount: 0,
|
|
51
|
-
}, optionsWithScope);
|
|
162
|
+
}, optionsWithScope, plan);
|
|
52
163
|
}
|
|
53
164
|
const projectRoot = resolve(optionsWithScope.projectRoot ?? process.cwd());
|
|
165
|
+
const reused = tryReuseVerifyAc(plan, acceptance, optionsWithScope, projectRoot);
|
|
166
|
+
if (reused !== null) {
|
|
167
|
+
return applyOracle(reused, optionsWithScope, plan);
|
|
168
|
+
}
|
|
54
169
|
// Prefer shared literal-acceptance path so safety / promotion rules stay one place.
|
|
55
170
|
// Empty plan.acceptance.commands still consults the #3267 rejected ledger
|
|
56
171
|
// (Greptile P1: rejected stated AC must never soft-pass).
|
|
@@ -66,12 +181,12 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
66
181
|
(optionsWithScope.checkIntegrated === true ? false : undefined),
|
|
67
182
|
quiet: optionsWithScope.quiet,
|
|
68
183
|
});
|
|
69
|
-
// When literal
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
184
|
+
// When the literal ledger produced no runs, execute non-empty plan.acceptance.commands
|
|
185
|
+
// as source=explicit. The documented key is plan.acceptance.commands (#3284 / #3449);
|
|
186
|
+
// the #3267 ledger is a parallel store and can be empty while stated commands exist.
|
|
187
|
+
// Stated was previously excluded, so rung=stated + empty ledger printed "nothing to run".
|
|
188
|
+
// Do not override a blocking rejected ledger or a config error.
|
|
189
|
+
if (shouldRunPlanAcceptanceDirectly(base, acceptance)) {
|
|
75
190
|
const runner = optionsWithScope.runner;
|
|
76
191
|
const direct = runLiteralAcceptanceCommands(acceptance.commands.map((c) => ({
|
|
77
192
|
command: c.command,
|
|
@@ -85,7 +200,17 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
85
200
|
runner,
|
|
86
201
|
allowTaskStatement: optionsWithScope.allowTaskStatement,
|
|
87
202
|
});
|
|
88
|
-
|
|
203
|
+
// Carry the #3484 demotion forward: the direct path replaces `base`, and the
|
|
204
|
+
// advisory ledger must stay visible (reported, never blocking) (#3497).
|
|
205
|
+
const advisory = base.advisoryRejected ?? [];
|
|
206
|
+
const directWithAdvisory = {
|
|
207
|
+
...direct,
|
|
208
|
+
advisoryRejected: advisory,
|
|
209
|
+
message: optionsWithScope.quiet === true
|
|
210
|
+
? direct.message
|
|
211
|
+
: appendLiteralAcceptanceAdvisory(direct.message, advisory),
|
|
212
|
+
};
|
|
213
|
+
return applyOracle(annotate(directWithAdvisory, acceptance, optionsWithScope.quiet), optionsWithScope, plan);
|
|
89
214
|
}
|
|
90
215
|
// Check composition: mid-story unpromoted capture-only may soft-pass so the
|
|
91
216
|
// framework graph is not deadlocked before agents promote peers.
|
|
@@ -94,7 +219,7 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
94
219
|
if (optionsWithScope.checkIntegrated === true && !base.ok && base.runs.length === 0) {
|
|
95
220
|
const hasRejected = (base.rejected?.length ?? 0) > 0;
|
|
96
221
|
if (hasRejected) {
|
|
97
|
-
return applyOracle(annotate(base, acceptance, optionsWithScope.quiet), optionsWithScope);
|
|
222
|
+
return applyOracle(annotate(base, acceptance, optionsWithScope.quiet), optionsWithScope, plan);
|
|
98
223
|
}
|
|
99
224
|
const unpromoted = /capture-only|task_statement|no matching agent-promoted/i.test(base.message) ||
|
|
100
225
|
(base.commands.length > 0 && base.commands.every((c) => c.source === "task_statement"));
|
|
@@ -122,10 +247,21 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
122
247
|
rejectedCount: base.rejected?.length ?? 0,
|
|
123
248
|
}),
|
|
124
249
|
resolvedCommandCount: base.commands.length,
|
|
125
|
-
}, optionsWithScope);
|
|
250
|
+
}, optionsWithScope, plan);
|
|
126
251
|
}
|
|
127
252
|
}
|
|
128
|
-
return applyOracle(annotate(base, acceptance, optionsWithScope.quiet), optionsWithScope);
|
|
253
|
+
return applyOracle(annotate(base, acceptance, optionsWithScope.quiet), optionsWithScope, plan);
|
|
254
|
+
}
|
|
255
|
+
function shouldRunPlanAcceptanceDirectly(base, acceptance) {
|
|
256
|
+
if (acceptance.commands.length === 0)
|
|
257
|
+
return false;
|
|
258
|
+
if (base.runs.length > 0)
|
|
259
|
+
return false;
|
|
260
|
+
if (base.code === 2)
|
|
261
|
+
return false;
|
|
262
|
+
if ((base.rejected?.length ?? 0) > 0)
|
|
263
|
+
return false;
|
|
264
|
+
return true;
|
|
129
265
|
}
|
|
130
266
|
function classifyResolution(input) {
|
|
131
267
|
if (input.resolution !== undefined) {
|
|
@@ -158,6 +294,17 @@ function applyEmptyFloorPolicy(result, options) {
|
|
|
158
294
|
}
|
|
159
295
|
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
160
296
|
const suiteFloor = options.hasSuiteFloor ?? projectHasSuiteFloor(projectRoot);
|
|
297
|
+
const skippedPrompts = result.transcriptPromptSkipped ?? 0;
|
|
298
|
+
if (suiteFloor && skippedPrompts > 0) {
|
|
299
|
+
return {
|
|
300
|
+
...result,
|
|
301
|
+
ok: false,
|
|
302
|
+
code: 1,
|
|
303
|
+
message: options.quiet === true ? "" : formatTranscriptEmptyMessage(result.acceptance),
|
|
304
|
+
resolution: "fail",
|
|
305
|
+
resolvedCommandCount: 0,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
161
308
|
if (suiteFloor) {
|
|
162
309
|
return {
|
|
163
310
|
...result,
|
|
@@ -185,6 +332,8 @@ function acceptanceOutcomeOf(result) {
|
|
|
185
332
|
return "fail";
|
|
186
333
|
if (result.resolution === "config")
|
|
187
334
|
return "config-error";
|
|
335
|
+
if (result.resolution === "rejected-noop")
|
|
336
|
+
return "rejected-noop";
|
|
188
337
|
return "soft-missing";
|
|
189
338
|
}
|
|
190
339
|
function emitAcceptanceObservedStamp(options, projectRoot) {
|
|
@@ -208,9 +357,9 @@ function emitAcceptanceOutcome(result, options, projectRoot) {
|
|
|
208
357
|
try {
|
|
209
358
|
const emitter = new RunSummaryEmitter({
|
|
210
359
|
projectRoot,
|
|
211
|
-
sessionId:
|
|
212
|
-
"verify-ac",
|
|
360
|
+
sessionId: options.sessionId,
|
|
213
361
|
env: options.env,
|
|
362
|
+
component: "verify-ac",
|
|
214
363
|
});
|
|
215
364
|
emitter.emitAcceptance({
|
|
216
365
|
resolved_command_count: result.resolvedCommandCount,
|
|
@@ -222,6 +371,7 @@ function emitAcceptanceOutcome(result, options, projectRoot) {
|
|
|
222
371
|
id: row.id,
|
|
223
372
|
outcome: row.outcome,
|
|
224
373
|
})),
|
|
374
|
+
served_from: result.servedFrom ?? "executed",
|
|
225
375
|
});
|
|
226
376
|
}
|
|
227
377
|
catch {
|
|
@@ -239,8 +389,14 @@ function emitAcceptanceTelemetry(result, options, projectRoot) {
|
|
|
239
389
|
*/
|
|
240
390
|
export function emitVerifyAcTerminalOutcome(input) {
|
|
241
391
|
emitAcceptanceOutcome({
|
|
242
|
-
ok: input.outcome !== "config-error" &&
|
|
243
|
-
|
|
392
|
+
ok: input.outcome !== "config-error" &&
|
|
393
|
+
input.outcome !== "fail" &&
|
|
394
|
+
input.outcome !== "rejected-noop",
|
|
395
|
+
code: input.outcome === "config-error"
|
|
396
|
+
? 2
|
|
397
|
+
: input.outcome === "fail" || input.outcome === "rejected-noop"
|
|
398
|
+
? 1
|
|
399
|
+
: 0,
|
|
244
400
|
message: "",
|
|
245
401
|
commands: [],
|
|
246
402
|
runs: [],
|
|
@@ -257,11 +413,13 @@ export function emitVerifyAcTerminalOutcome(input) {
|
|
|
257
413
|
? "skipped"
|
|
258
414
|
: input.outcome === "fail"
|
|
259
415
|
? "fail"
|
|
260
|
-
: input.outcome === "
|
|
261
|
-
? "
|
|
262
|
-
: input.outcome === "
|
|
263
|
-
? "
|
|
264
|
-
: "
|
|
416
|
+
: input.outcome === "rejected-noop"
|
|
417
|
+
? "rejected-noop"
|
|
418
|
+
: input.outcome === "soft_empty"
|
|
419
|
+
? "soft_empty"
|
|
420
|
+
: input.outcome === "verified-pass"
|
|
421
|
+
? "verified-pass"
|
|
422
|
+
: "empty-pass",
|
|
265
423
|
resolvedCommandCount: 0,
|
|
266
424
|
}, { projectRoot: input.projectRoot, env: input.env }, resolve(input.projectRoot));
|
|
267
425
|
}
|
|
@@ -273,7 +431,16 @@ function applyClauseWalk(result, options) {
|
|
|
273
431
|
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
274
432
|
const report = walkAcceptanceClauses(clauses, projectRoot);
|
|
275
433
|
const message = options.quiet ? result.message : formatClauseWalkMessage(report, result.message);
|
|
276
|
-
|
|
434
|
+
// #3497: a clause the static walk cannot decide is evidence of nothing. It blocks
|
|
435
|
+
// only when nothing else verified the product; a green executable acceptance run
|
|
436
|
+
// already is the product-first oracle. Failed clauses still block unconditionally.
|
|
437
|
+
const blocked = clauseWalkBlocks({
|
|
438
|
+
failed: report.failed.length,
|
|
439
|
+
verified: report.verified.length,
|
|
440
|
+
walked: report.clauses.length,
|
|
441
|
+
hasGreenExecutableRun: result.ok && result.runs.length > 0 && result.runs.every((run) => run.ok),
|
|
442
|
+
});
|
|
443
|
+
const ok = result.ok && !blocked;
|
|
277
444
|
return {
|
|
278
445
|
...result,
|
|
279
446
|
ok,
|
|
@@ -288,9 +455,49 @@ function applyClauseWalk(result, options) {
|
|
|
288
455
|
clauseWalked: true,
|
|
289
456
|
};
|
|
290
457
|
}
|
|
291
|
-
function
|
|
458
|
+
function applyRejectedNoop(result) {
|
|
459
|
+
if (result.resolution === "rejected-noop") {
|
|
460
|
+
return result;
|
|
461
|
+
}
|
|
462
|
+
const rejected = result.rejected ?? [];
|
|
463
|
+
const fromLedger = rejected.some((row) => isNoopRefusalReason(row.reason));
|
|
464
|
+
const fromRuns = result.runs.some((row) => !row.ok && isNoopRefusalReason(row.detail.replace(/^refused:\s*/i, "")));
|
|
465
|
+
// #3484 / #3497: the advisory block quotes refusal reasons that were deliberately
|
|
466
|
+
// demoted because the plan states structured acceptance commands. Sniffing the
|
|
467
|
+
// rendered message resurrected them as a blocking no-op verdict — verify:ac
|
|
468
|
+
// refused while its own output said "do NOT block". Read the blocking ledgers,
|
|
469
|
+
// and inspect only the non-advisory part of the message.
|
|
470
|
+
const fromMessage = isNoopRefusalReason(stripLiteralAcceptanceAdvisory(result.message));
|
|
471
|
+
if (!fromLedger && !fromRuns && !fromMessage) {
|
|
472
|
+
return result;
|
|
473
|
+
}
|
|
474
|
+
return {
|
|
475
|
+
...result,
|
|
476
|
+
ok: false,
|
|
477
|
+
code: result.code === 2 ? 2 : 1,
|
|
478
|
+
resolution: "rejected-noop",
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Make the rendered message agree with the verdict (#3497).
|
|
483
|
+
*
|
|
484
|
+
* `annotate` stamps "verify:ac passed" from the sub-gate result, but later stages
|
|
485
|
+
* (clause walk, no-op ledger, oracle integrity) can still flip `ok`. The old output
|
|
486
|
+
* left the stale "passed" lead in place, so scope:complete printed four passing lines
|
|
487
|
+
* and then refused. Re-label the lead and name the deciding predicate.
|
|
488
|
+
*/
|
|
489
|
+
function labelVerdict(result) {
|
|
490
|
+
const verdict = resolveAcceptanceVerdict(result);
|
|
491
|
+
if (verdict.ok) {
|
|
492
|
+
return result.message;
|
|
493
|
+
}
|
|
494
|
+
const relabelled = result.message.replace(/verify:ac passed \(#3284\)/g, "verify:ac FAILED (#3284)");
|
|
495
|
+
const line = formatAcceptanceVerdict(verdict);
|
|
496
|
+
return relabelled.length > 0 ? `${relabelled}\n${line}` : line;
|
|
497
|
+
}
|
|
498
|
+
function applyOracle(result, options, plan = {}) {
|
|
292
499
|
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
293
|
-
const walked = applyClauseWalk(result, options);
|
|
500
|
+
const walked = applyClauseWalk(applyRejectedNoop(result), options);
|
|
294
501
|
const gated = walked.clauseWalked === true ? walked : applyEmptyFloorPolicy(walked, options);
|
|
295
502
|
// Emit/read disk only when the caller supplied env (CLI passes process.env).
|
|
296
503
|
// Tests stay isolated unless they opt in with env or runSummaryText.
|
|
@@ -310,14 +517,23 @@ function applyOracle(result, options) {
|
|
|
310
517
|
env: options.env,
|
|
311
518
|
});
|
|
312
519
|
next = mergeOracleVerdict(gated, verdict);
|
|
313
|
-
if (!verdict.ok &&
|
|
520
|
+
if (!verdict.ok &&
|
|
521
|
+
next.resolution !== "soft_empty" &&
|
|
522
|
+
next.resolution !== "config" &&
|
|
523
|
+
next.resolution !== "rejected-noop") {
|
|
314
524
|
next = { ...next, resolution: "fail" };
|
|
315
525
|
}
|
|
316
526
|
}
|
|
527
|
+
const stamped = {
|
|
528
|
+
...next,
|
|
529
|
+
message: options.quiet === true ? next.message : labelVerdict(next),
|
|
530
|
+
servedFrom: next.servedFrom ?? "executed",
|
|
531
|
+
};
|
|
532
|
+
persistVerifyAcSessionCache(stamped, options, projectRoot, plan);
|
|
317
533
|
if (options.skipAcceptanceEmit !== true) {
|
|
318
|
-
emitAcceptanceTelemetry(
|
|
534
|
+
emitAcceptanceTelemetry(stamped, options, projectRoot);
|
|
319
535
|
}
|
|
320
|
-
return
|
|
536
|
+
return stamped;
|
|
321
537
|
}
|
|
322
538
|
function annotate(result, acceptance, quiet) {
|
|
323
539
|
const prefix = result.ok
|
|
@@ -353,6 +569,7 @@ function annotate(result, acceptance, quiet) {
|
|
|
353
569
|
rejectedCount: result.rejected?.length ?? 0,
|
|
354
570
|
}),
|
|
355
571
|
resolvedCommandCount: result.runs.length > 0 ? result.runs.length : commandCount,
|
|
572
|
+
servedFrom: "executed",
|
|
356
573
|
};
|
|
357
574
|
}
|
|
358
575
|
/**
|
|
@@ -435,11 +652,17 @@ function maybeAttachAcPassBank(result, plan, xbriefPath, options) {
|
|
|
435
652
|
.replace(/\.xbrief\.json$/i, "")
|
|
436
653
|
.replace(/\.vbrief\.json$/i, "");
|
|
437
654
|
try {
|
|
655
|
+
const hashed = hashProductState({
|
|
656
|
+
projectRoot,
|
|
657
|
+
plan,
|
|
658
|
+
productPaths: options.productPaths,
|
|
659
|
+
});
|
|
438
660
|
const banked = maybeBankOnAcPass({
|
|
439
661
|
projectRoot,
|
|
440
662
|
scopeId,
|
|
441
663
|
executableRuns: result.runs.length,
|
|
442
664
|
quiet: options.quiet,
|
|
665
|
+
productStateHash: hashed.complete ? hashed.digest : null,
|
|
443
666
|
});
|
|
444
667
|
if (options.quiet || banked.notes.length === 0) {
|
|
445
668
|
return result;
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* acceptance.commands schema, verify:ac evaluation, check-mode composition
|
|
5
5
|
* (AC-first, hygiene advisory under pressure, rapid=AC-only).
|
|
6
6
|
*/
|
|
7
|
+
export type { AcServedFrom } from "../session/verify-ac-session-cache.js";
|
|
7
8
|
export { attachPlanAcceptance, buildAcceptanceFromIntakeCapture, readPlanAcceptance, stampAcceptanceFromLiteralCapture, validatePlanAcceptance, } from "./acceptance.js";
|
|
9
|
+
export { type AcceptanceGateProfileOptions, type AcceptancePredicate, type AcceptanceReaderProfile, type AcceptanceReading, type AcceptanceVerdict, clauseWalkBlocks, formatAcceptanceVerdict, resolveAcceptanceGateProfile, resolveAcceptanceVerdict, resolvedAcceptanceCommandCount, } from "./acceptance-resolver.js";
|
|
8
10
|
export { applyProductFirstGateMode, isHygieneGate, isProductAcGate, type ProductFirstCheckModeResolution, type ResolveProductFirstCheckModeInput, resolveProductFirstCheckMode, } from "./check-mode.js";
|
|
9
11
|
export { EMPTY_AC_CAUSE, EMPTY_AC_OUTCOME, EMPTY_AC_REMEDY, formatSoftEmptyMessage, isEmptyAcResolution, isSoftEmptyAcText, projectHasSuiteFloor, type VerifyAcResolution, } from "./empty-resolution.js";
|
|
10
12
|
export { type EvaluateVerifyAcOptions, emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, evaluateVerifyAcFromPlan, isVerifyAcRequiredAtCeremonyDepth, resolveOracleScopeKey, type VerifyAcResult, } from "./evaluate.js";
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* (AC-first, hygiene advisory under pressure, rapid=AC-only).
|
|
6
6
|
*/
|
|
7
7
|
export { attachPlanAcceptance, buildAcceptanceFromIntakeCapture, readPlanAcceptance, stampAcceptanceFromLiteralCapture, validatePlanAcceptance, } from "./acceptance.js";
|
|
8
|
+
export { clauseWalkBlocks, formatAcceptanceVerdict, resolveAcceptanceGateProfile, resolveAcceptanceVerdict, resolvedAcceptanceCommandCount, } from "./acceptance-resolver.js";
|
|
8
9
|
export { applyProductFirstGateMode, isHygieneGate, isProductAcGate, resolveProductFirstCheckMode, } from "./check-mode.js";
|
|
9
10
|
export { EMPTY_AC_CAUSE, EMPTY_AC_OUTCOME, EMPTY_AC_REMEDY, formatSoftEmptyMessage, isEmptyAcResolution, isSoftEmptyAcText, projectHasSuiteFloor, } from "./empty-resolution.js";
|
|
10
11
|
export { emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, evaluateVerifyAcFromPlan, isVerifyAcRequiredAtCeremonyDepth, resolveOracleScopeKey, } from "./evaluate.js";
|
|
@@ -1,7 +1,104 @@
|
|
|
1
|
+
import { lstatSync } from "node:fs";
|
|
2
|
+
/**
|
|
3
|
+
* Shared "not product source" core (#3487) plus the coverage artifacts only the
|
|
4
|
+
* release archive names. Scratch and agent worktrees are never shippable
|
|
5
|
+
* framework content (#2953). The archive set is git-tracked files (#3490); this
|
|
6
|
+
* denylist is defence in depth, including for a tracked path under a core name.
|
|
7
|
+
*
|
|
8
|
+
* Callers may still widen this per run via `extraExcludes` / `--exclude-extra`.
|
|
9
|
+
*/
|
|
1
10
|
export declare const DEFAULT_EXCLUDES: Set<string>;
|
|
2
11
|
export declare const DEFAULT_EXCLUDED_PATH_PREFIXES: readonly ["history/archive", "vbrief/completed", "vbrief/cancelled"];
|
|
12
|
+
/**
|
|
13
|
+
* Generated outputs that may be packed even when untracked. Empty by default:
|
|
14
|
+
* the release archive is a source distribution, so extra outputs must be named
|
|
15
|
+
* explicitly (#3490).
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_GENERATED_ALLOWLIST: readonly string[];
|
|
3
18
|
export declare const ARCHIVE_ROOT = "deft";
|
|
4
19
|
export declare const CONTENT_PREFIX = "content/";
|
|
20
|
+
/** Raised when the resolved archive set contains an untracked surprise (#3490). */
|
|
21
|
+
export declare class UntrackedArchiveEntryError extends Error {
|
|
22
|
+
readonly paths: readonly string[];
|
|
23
|
+
constructor(paths: readonly string[]);
|
|
24
|
+
}
|
|
25
|
+
export type ArchiveSourceEntry = {
|
|
26
|
+
absPath: string | Buffer;
|
|
27
|
+
archiveRel: string;
|
|
28
|
+
archiveRelBytes: Buffer;
|
|
29
|
+
};
|
|
30
|
+
/** Private-use mark so archiver's string `name` can carry raw member bytes. */
|
|
31
|
+
export declare const ARCHIVE_BINARY_NAME_MARK = "\uF000";
|
|
32
|
+
export declare function flattenContentPrefixBytes(relBytes: Buffer): Buffer;
|
|
33
|
+
export declare function isValidUtf8Buffer(buf: Buffer): boolean;
|
|
34
|
+
export declare function archiveMemberBytes(archiveRelBytes: Buffer): Buffer;
|
|
35
|
+
/** Archiver `file()`/`append` name: UTF-8 text, or marked latin1 of raw bytes. */
|
|
36
|
+
export declare function archiverEntryName(memberBytes: Buffer): string;
|
|
37
|
+
/** Original `ls-files -z` segment bytes plus the display/skip string. */
|
|
38
|
+
export type GitLsFilesPath = {
|
|
39
|
+
readonly relPosix: string;
|
|
40
|
+
readonly bytes: Buffer;
|
|
41
|
+
};
|
|
42
|
+
export type ArchiveFsLookup = {
|
|
43
|
+
realpathSync: (path: string | Buffer, options?: {
|
|
44
|
+
encoding?: BufferEncoding | "buffer" | null;
|
|
45
|
+
}) => string | Buffer;
|
|
46
|
+
lstatSync: (path: string | Buffer) => ReturnType<typeof lstatSync>;
|
|
47
|
+
};
|
|
48
|
+
/** `-z` stdout is a NUL-separated byte stream; never UTF-8-decode it whole. */
|
|
49
|
+
export declare const GIT_LS_FILES_Z_ENCODING: null;
|
|
50
|
+
export type GitLsFilesZSpawn = (command: string, args: readonly string[], options: {
|
|
51
|
+
encoding: null;
|
|
52
|
+
timeout?: number;
|
|
53
|
+
maxBuffer?: number;
|
|
54
|
+
stdio?: readonly ["ignore", "pipe", "pipe"];
|
|
55
|
+
}) => {
|
|
56
|
+
status: number | null;
|
|
57
|
+
stdout?: Buffer | string | null;
|
|
58
|
+
stderr?: Buffer | string | null;
|
|
59
|
+
error?: Error | null;
|
|
60
|
+
signal?: NodeJS.Signals | null;
|
|
61
|
+
};
|
|
62
|
+
/** Decode one `ls-files -z` segment; keep non-UTF-8 bytes as latin1. */
|
|
63
|
+
export declare function decodeGitLsFilesPath(segment: Buffer): string;
|
|
64
|
+
/** Split a raw `git ls-files -z` Buffer on 0x00, keeping original path bytes. */
|
|
65
|
+
export declare function splitGitLsFilesZRecords(stdout: Buffer): GitLsFilesPath[];
|
|
66
|
+
/** Split a raw `git ls-files -z` Buffer on 0x00, then decode each path. */
|
|
67
|
+
export declare function splitGitLsFilesZ(stdout: Buffer): string[];
|
|
68
|
+
/**
|
|
69
|
+
* Return `git ls-files -z` paths with original bytes. Fail closed when git
|
|
70
|
+
* cannot enumerate tracked files -- a walk would pack host-local untracked
|
|
71
|
+
* state (#3490).
|
|
72
|
+
*/
|
|
73
|
+
export declare function listGitTrackedPathRecords(root: string, spawn?: GitLsFilesZSpawn): GitLsFilesPath[];
|
|
74
|
+
/** Return `git ls-files -z` paths in POSIX form. */
|
|
75
|
+
export declare function listGitTrackedFiles(root: string, spawn?: GitLsFilesZSpawn): string[];
|
|
76
|
+
/**
|
|
77
|
+
* Fail closed when any resolved archive path is untracked and not on the
|
|
78
|
+
* generated-output allowlist (#3490).
|
|
79
|
+
*/
|
|
80
|
+
export declare function assertArchiveEntriesTrackedOrGenerated(root: string, rels: readonly string[], generatedAllowlist?: readonly string[], spawn?: GitLsFilesZSpawn): void;
|
|
81
|
+
export type ResolveArchiveEntriesOptions = {
|
|
82
|
+
readonly extraExcludes?: readonly string[];
|
|
83
|
+
readonly excludedPrefixes?: readonly string[];
|
|
84
|
+
readonly generatedAllowlist?: readonly string[];
|
|
85
|
+
readonly spawn?: GitLsFilesZSpawn;
|
|
86
|
+
readonly fs?: ArchiveFsLookup;
|
|
87
|
+
};
|
|
88
|
+
/** Join canonical root bytes with original git path bytes; convert POSIX `/` to OS sep. */
|
|
89
|
+
export declare function joinRootAndRelBytes(rootBytes: Buffer, relBytes: Buffer): Buffer;
|
|
90
|
+
/**
|
|
91
|
+
* String path when the `-z` segment is valid UTF-8; otherwise a Buffer that
|
|
92
|
+
* keeps the original filename bytes for fs lookup (#3490 residual).
|
|
93
|
+
*/
|
|
94
|
+
export declare function fsLookupPath(root: string, relPosix: string, bytes: Buffer, rootBytes?: Buffer): string | Buffer | null;
|
|
95
|
+
/** Resolve a POSIX rel path under root, or null if it escapes (#3490 review). */
|
|
96
|
+
export declare function containedAbsPath(root: string, relPosix: string): string | null;
|
|
97
|
+
/**
|
|
98
|
+
* Derive the archive file set from git-tracked paths plus an explicit
|
|
99
|
+
* generated-output allowlist. The basename denylist remains defence in depth.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveArchiveEntries(root: string, options?: ResolveArchiveEntriesOptions): ArchiveSourceEntry[];
|
|
5
102
|
export declare function iterSourceFiles(root: string, excludes?: ReadonlySet<string>, excludedPrefixes?: readonly string[]): Array<{
|
|
6
103
|
absPath: string;
|
|
7
104
|
archiveRel: string;
|
|
@@ -16,8 +113,12 @@ export type BuildProgress = {
|
|
|
16
113
|
};
|
|
17
114
|
export type BuildArchiveOptions = {
|
|
18
115
|
readonly extraExcludes?: readonly string[];
|
|
116
|
+
/** Untracked generated outputs that may be packed (#3490). */
|
|
117
|
+
readonly generatedAllowlist?: readonly string[];
|
|
19
118
|
/** Progress sink; default silent so unit tests stay quiet (#2953). */
|
|
20
119
|
readonly onProgress?: (p: BuildProgress) => void;
|
|
120
|
+
readonly spawn?: GitLsFilesZSpawn;
|
|
121
|
+
readonly fs?: ArchiveFsLookup;
|
|
21
122
|
};
|
|
22
123
|
/**
|
|
23
124
|
* Emit human-readable stage progress for long release packaging runs (#2953).
|