@deftai/directive-core 0.103.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 +682 -35
- package/dist/check/cached-orchestrator.d.ts +1 -1
- package/dist/check/cached-orchestrator.js +2 -2
- package/dist/check/gate-lists.d.ts +3 -2
- package/dist/check/gate-lists.js +5 -2
- package/dist/check/index.d.ts +1 -0
- package/dist/check/index.js +1 -0
- package/dist/check/named-cause.d.ts +1 -1
- package/dist/check/named-cause.js +33 -3
- package/dist/check/session-completed-ac.d.ts +39 -0
- package/dist/check/session-completed-ac.js +198 -0
- 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 -14
- package/dist/doctor/types.d.ts +9 -0
- package/dist/fs/contained-write.d.ts +115 -1
- package/dist/fs/contained-write.js +242 -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 +2 -0
- package/dist/index.js +3 -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 +74 -0
- package/dist/intake/clause-derivation.js +409 -0
- package/dist/intake/index.d.ts +1 -0
- package/dist/intake/index.js +1 -0
- package/dist/intake/issue-ingest.d.ts +3 -1
- package/dist/intake/issue-ingest.js +36 -43
- 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 +9 -0
- package/dist/preflight/evaluate.js +49 -1
- package/dist/preflight/index.d.ts +5 -1
- 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 +5 -2
- package/dist/product-first-done-gate/empty-resolution.js +13 -2
- package/dist/product-first-done-gate/evaluate.d.ts +29 -0
- package/dist/product-first-done-gate/evaluate.js +307 -33
- package/dist/product-first-done-gate/index.d.ts +3 -1
- package/dist/product-first-done-gate/index.js +2 -1
- package/dist/release/build-dist.d.ts +101 -0
- package/dist/release/build-dist.js +428 -46
- package/dist/run-summary/emit.d.ts +50 -4
- package/dist/run-summary/emit.js +262 -26
- 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/share.d.ts +1 -1
- package/dist/run-summary/share.js +2 -2
- package/dist/run-summary/types.d.ts +38 -6
- package/dist/run-summary/types.js +1 -0
- package/dist/scope/acceptance-activate-gate.d.ts +1 -1
- package/dist/scope/acceptance-activate-gate.js +4 -4
- package/dist/scope/acceptance-evidence.d.ts +27 -0
- package/dist/scope/acceptance-evidence.js +66 -0
- package/dist/scope/capacity-stamp.d.ts +2 -0
- package/dist/scope/capacity-stamp.js +4 -0
- package/dist/scope/delivery-evidence.d.ts +9 -3
- package/dist/scope/delivery-evidence.js +39 -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 +66 -4
- 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/ceremony-dial-evidence.d.ts +42 -0
- package/dist/session/ceremony-dial-evidence.js +194 -0
- package/dist/session/git.js +19 -4
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.js +5 -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 +88 -5
- 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 +21 -4
- package/dist/slice/lock.d.ts +16 -1
- package/dist/slice/lock.js +137 -11
- package/dist/slice/record.d.ts +8 -5
- package/dist/slice/record.js +21 -13
- 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/evaluate.d.ts +42 -0
- package/dist/telemetry-coverage/evaluate.js +148 -0
- package/dist/telemetry-coverage/fake-trial.d.ts +45 -0
- package/dist/telemetry-coverage/fake-trial.js +204 -0
- package/dist/telemetry-coverage/index.d.ts +5 -0
- package/dist/telemetry-coverage/index.js +5 -0
- package/dist/telemetry-coverage/kinds.d.ts +19 -0
- package/dist/telemetry-coverage/kinds.js +54 -0
- package/dist/telemetry-coverage/scan-callers.d.ts +25 -0
- package/dist/telemetry-coverage/scan-callers.js +168 -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 +3 -1
- package/dist/vbrief-reconcile/index.js +2 -1
- package/dist/vbrief-reconcile/origin-freshness.d.ts +44 -0
- package/dist/vbrief-reconcile/origin-freshness.js +221 -0
- 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/index.d.ts +1 -0
- package/dist/verify-source/index.js +1 -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
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* ITEM_CORE is not expanded with bare keys; verify:vbrief-conformance rejects them.
|
|
14
14
|
*/
|
|
15
15
|
import type { GrantOrigin } from "../authz/types.js";
|
|
16
|
+
import { type AcceptancePredicate } from "../product-first-done-gate/acceptance-resolver.js";
|
|
17
|
+
import { type EvaluateVerifyAcOptions } from "../product-first-done-gate/evaluate.js";
|
|
16
18
|
/** Canonical namespaced key for typed acceptance evidence (#3305 / #1620). */
|
|
17
19
|
export declare const ACCEPTANCE_EVIDENCE_KEY: "x-directive/evidence";
|
|
18
20
|
/** Canonical namespaced key for human-origin disposition (#3305 / #1620). */
|
|
@@ -55,6 +57,10 @@ export interface AcceptanceEvidenceGateResult {
|
|
|
55
57
|
readonly ok: boolean;
|
|
56
58
|
readonly message: string;
|
|
57
59
|
readonly reports: readonly CriterionAcceptanceReport[];
|
|
60
|
+
/** How the #3357 walk obtained AC (#3387). */
|
|
61
|
+
readonly servedFrom?: "bank" | "cache" | "executed";
|
|
62
|
+
/** Which acceptance check decided the walk (#3497). Undefined when no walk ran. */
|
|
63
|
+
readonly predicate?: AcceptancePredicate;
|
|
58
64
|
}
|
|
59
65
|
export declare function isAcceptanceEvidenceKind(value: unknown): value is AcceptanceEvidenceKind;
|
|
60
66
|
export declare function isAcceptanceDispositionKind(value: unknown): value is AcceptanceDispositionKind;
|
|
@@ -98,6 +104,27 @@ export declare function stampNamespacedEvidence(item: Record<string, unknown>, r
|
|
|
98
104
|
* cannot carry both acceptance fields after a replace (#3305 Greptile P2).
|
|
99
105
|
*/
|
|
100
106
|
export declare function stampNamespacedDisposition(item: Record<string, unknown>, record: AcceptanceDispositionRecord): void;
|
|
107
|
+
/**
|
|
108
|
+
* Standing contract for scope:complete's acceptance precondition (#3357 / #3497).
|
|
109
|
+
*
|
|
110
|
+
* It no longer asserts a predicate ("empty or failing") — the actual predicate is
|
|
111
|
+
* named per refusal by the shared resolver. It also no longer tells operators to
|
|
112
|
+
* stamp by running verify:ac: verify:ac is the verifier and never writes the brief
|
|
113
|
+
* (a verifier that authors the acceptance it then checks is not a gate). Stamping
|
|
114
|
+
* happens at intake / promote via clause derivation (#3323).
|
|
115
|
+
*/
|
|
116
|
+
export declare const SCOPE_COMPLETE_ACCEPTANCE_REMEDIATION: string;
|
|
117
|
+
/**
|
|
118
|
+
* Hard precondition for scope:complete (#3357 / #3267 / #3284).
|
|
119
|
+
*
|
|
120
|
+
* Runs the same verify:ac walk check uses, through the one shared option profile and
|
|
121
|
+
* the one shared verdict resolver (#3497) — so scope:complete can no longer report a
|
|
122
|
+
* different story than verify:ac about the same artifact. Disposition on plan items
|
|
123
|
+
* does not skip it. Briefs with no stamped plan.acceptance and no executable commands
|
|
124
|
+
* keep the legacy #3267 "nothing to run" pass so existing evidence-only fixtures stay
|
|
125
|
+
* valid.
|
|
126
|
+
*/
|
|
127
|
+
export declare function evaluateScopeCompleteAcceptanceWalk(plan: Record<string, unknown>, options?: EvaluateVerifyAcOptions): AcceptanceEvidenceGateResult;
|
|
101
128
|
/**
|
|
102
129
|
* Fail closed when any non-terminal plan item lacks suitable evidence or a human-origin disposition.
|
|
103
130
|
*/
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* ITEM_CORE is not expanded with bare keys; verify:vbrief-conformance rejects them.
|
|
14
14
|
*/
|
|
15
15
|
import { isHumanOrigin } from "../authz/origin.js";
|
|
16
|
+
import { formatAcceptanceVerdict, resolveAcceptanceGateProfile, resolveAcceptanceVerdict, } from "../product-first-done-gate/acceptance-resolver.js";
|
|
17
|
+
import { evaluateVerifyAcFromPlan, } from "../product-first-done-gate/evaluate.js";
|
|
16
18
|
/** Canonical namespaced key for typed acceptance evidence (#3305 / #1620). */
|
|
17
19
|
export const ACCEPTANCE_EVIDENCE_KEY = "x-directive/evidence";
|
|
18
20
|
/** Canonical namespaced key for human-origin disposition (#3305 / #1620). */
|
|
@@ -369,6 +371,70 @@ function walkItems(items, pathPrefix, reports) {
|
|
|
369
371
|
walkItems(obj.items, `${path}.items`, reports);
|
|
370
372
|
});
|
|
371
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Standing contract for scope:complete's acceptance precondition (#3357 / #3497).
|
|
376
|
+
*
|
|
377
|
+
* It no longer asserts a predicate ("empty or failing") — the actual predicate is
|
|
378
|
+
* named per refusal by the shared resolver. It also no longer tells operators to
|
|
379
|
+
* stamp by running verify:ac: verify:ac is the verifier and never writes the brief
|
|
380
|
+
* (a verifier that authors the acceptance it then checks is not a gate). Stamping
|
|
381
|
+
* happens at intake / promote via clause derivation (#3323).
|
|
382
|
+
*/
|
|
383
|
+
export const SCOPE_COMPLETE_ACCEPTANCE_REMEDIATION = "scope:complete requires executable plan.acceptance that runs green; stamp commands on " +
|
|
384
|
+
"plan.acceptance.commands (or plan.metadata.swarm.verify_commands) — task verify:ac verifies, " +
|
|
385
|
+
"it does not stamp — then re-run task verify:ac -- <completing-xbrief> " +
|
|
386
|
+
"(disposition is not a substitute) (#3357/#3497)";
|
|
387
|
+
/**
|
|
388
|
+
* Hard precondition for scope:complete (#3357 / #3267 / #3284).
|
|
389
|
+
*
|
|
390
|
+
* Runs the same verify:ac walk check uses, through the one shared option profile and
|
|
391
|
+
* the one shared verdict resolver (#3497) — so scope:complete can no longer report a
|
|
392
|
+
* different story than verify:ac about the same artifact. Disposition on plan items
|
|
393
|
+
* does not skip it. Briefs with no stamped plan.acceptance and no executable commands
|
|
394
|
+
* keep the legacy #3267 "nothing to run" pass so existing evidence-only fixtures stay
|
|
395
|
+
* valid.
|
|
396
|
+
*/
|
|
397
|
+
export function evaluateScopeCompleteAcceptanceWalk(plan, options = {}) {
|
|
398
|
+
const stamped = plan.acceptance !== undefined;
|
|
399
|
+
const profile = resolveAcceptanceGateProfile("complete");
|
|
400
|
+
const walk = evaluateVerifyAcFromPlan(plan, {
|
|
401
|
+
...options,
|
|
402
|
+
checkIntegrated: profile.checkIntegrated,
|
|
403
|
+
captureFromNarratives: options.captureFromNarratives ?? profile.captureFromNarratives,
|
|
404
|
+
reuseMode: options.reuseMode ?? profile.reuseMode,
|
|
405
|
+
});
|
|
406
|
+
const rejectedCount = walk.rejected?.length ?? 0;
|
|
407
|
+
const hadWork = walk.runs.length > 0 || walk.commands.length > 0 || rejectedCount > 0;
|
|
408
|
+
const servedFrom = walk.servedFrom ?? "executed";
|
|
409
|
+
if (!stamped && !hadWork) {
|
|
410
|
+
return {
|
|
411
|
+
ok: true,
|
|
412
|
+
message: "Acceptance walk not required (no stamped plan.acceptance) (#3357)",
|
|
413
|
+
reports: [],
|
|
414
|
+
servedFrom: "executed",
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
const verdict = resolveAcceptanceVerdict(walk);
|
|
418
|
+
if (walk.ok) {
|
|
419
|
+
return {
|
|
420
|
+
ok: true,
|
|
421
|
+
message: walk.message,
|
|
422
|
+
reports: [],
|
|
423
|
+
servedFrom,
|
|
424
|
+
predicate: verdict.predicate,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
return {
|
|
428
|
+
ok: false,
|
|
429
|
+
// Name the check that refused and the value it read BEFORE the standing
|
|
430
|
+
// contract, so the first line the operator sees is the actual cause (#3497).
|
|
431
|
+
message: `scope:complete refused acceptance — ${formatAcceptanceVerdict(verdict)}\n` +
|
|
432
|
+
`${SCOPE_COMPLETE_ACCEPTANCE_REMEDIATION}\n${walk.message}`,
|
|
433
|
+
reports: [],
|
|
434
|
+
servedFrom,
|
|
435
|
+
predicate: verdict.predicate,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
372
438
|
/**
|
|
373
439
|
* Fail closed when any non-terminal plan item lacks suitable evidence or a human-origin disposition.
|
|
374
440
|
*/
|
|
@@ -19,6 +19,8 @@ export interface StampCompletionOptions {
|
|
|
19
19
|
* tests so the fallback path is exercised without a network call.
|
|
20
20
|
*/
|
|
21
21
|
readonly liveLabelReader?: LabelReader;
|
|
22
|
+
/** Session that ran scope:complete; check uses this to target xbrief/completed (#3357). */
|
|
23
|
+
readonly completedSessionId?: string | null;
|
|
22
24
|
}
|
|
23
25
|
/** Stamp completedAt + label-matched capacityBucket onto a completing vBRIEF (#1419, #2237). */
|
|
24
26
|
export declare function stampCompletionMetadata(plan: Record<string, unknown>, projectRoot: string, timestamp: string, options?: StampCompletionOptions): void;
|
|
@@ -86,6 +86,10 @@ export function stampCompletionMetadata(plan, projectRoot, timestamp, options =
|
|
|
86
86
|
}
|
|
87
87
|
const meta = metadata;
|
|
88
88
|
meta.completedAt = timestamp;
|
|
89
|
+
const sessionId = options.completedSessionId?.trim() ?? "";
|
|
90
|
+
if (sessionId.length > 0) {
|
|
91
|
+
meta.completedSessionId = sessionId;
|
|
92
|
+
}
|
|
89
93
|
const existing = meta.capacityBucket;
|
|
90
94
|
if (typeof existing === "string" && existing.trim().length > 0) {
|
|
91
95
|
return;
|
|
@@ -32,6 +32,8 @@ export interface CompletionProvenance {
|
|
|
32
32
|
readonly deployed: boolean | null;
|
|
33
33
|
/** Always null unless explicitly supplied — never inferred from Git (#3041). */
|
|
34
34
|
readonly uatVerified: boolean | null;
|
|
35
|
+
/** Session that completed the brief; used by check to target xbrief/completed (#3357). */
|
|
36
|
+
readonly completedSessionId?: string | null;
|
|
35
37
|
}
|
|
36
38
|
export interface DeliveryEvidenceInput {
|
|
37
39
|
readonly repository?: string | null;
|
|
@@ -67,6 +69,10 @@ export interface DeliveryGateResult {
|
|
|
67
69
|
readonly provenance: CompletionProvenance | null;
|
|
68
70
|
readonly codeBearing: boolean;
|
|
69
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Session id for a completing brief (#3357). Prefer DEFT_SESSION_ID, then ritual-state.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveCompletionSessionId(projectRoot: string, env?: NodeJS.ProcessEnv): string | null;
|
|
70
76
|
export declare function isNonDeliveryDisposition(value: unknown): value is NonDeliveryDisposition;
|
|
71
77
|
/** True when the brief is treated as code-bearing for the delivery gate (#3041). */
|
|
72
78
|
export declare function isCodeBearingScope(plan: Record<string, unknown>): boolean;
|
|
@@ -93,13 +99,13 @@ export declare function verifyDeliveryAncestry(projectRoot: string, mergeCommit:
|
|
|
93
99
|
remoteTip: string | null;
|
|
94
100
|
};
|
|
95
101
|
/**
|
|
96
|
-
* Gate delivered completion for a code-bearing scope (#3041).
|
|
102
|
+
* Gate delivered completion for a code-bearing scope (#3041 / #3380).
|
|
97
103
|
*
|
|
98
104
|
* Returns ok=true with provenance when:
|
|
99
105
|
* - scope is not code-bearing (provenance may be null or non-code note), OR
|
|
100
106
|
* - explicit non-delivery disposition is provided, OR
|
|
101
|
-
* -
|
|
102
|
-
*
|
|
107
|
+
* - merge commit is an ancestor of the refreshed remote delivery ref (prBase is
|
|
108
|
+
* provenance only; it need not equal deliveryBranch).
|
|
103
109
|
*/
|
|
104
110
|
export declare function evaluateDeliveryGate(options: DeliveryGateOptions): DeliveryGateResult;
|
|
105
111
|
/** Stamp completion provenance onto plan.metadata (mutates plan). */
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { resolveDeliveryBranch } from "../policy/delivery-branch.js";
|
|
11
11
|
import { defaultGitRunner, gitIsAncestor } from "../session/git.js";
|
|
12
|
+
import { readRitualState } from "../session/ritual-sentinel.js";
|
|
12
13
|
/** Handoff states that Git delivery can assert (deploy/UAT never inferred). */
|
|
13
14
|
export const HANDOFF_STATES = [
|
|
14
15
|
"implemented",
|
|
@@ -29,6 +30,18 @@ function asRecord(value) {
|
|
|
29
30
|
}
|
|
30
31
|
return null;
|
|
31
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Session id for a completing brief (#3357). Prefer DEFT_SESSION_ID, then ritual-state.
|
|
35
|
+
*/
|
|
36
|
+
export function resolveCompletionSessionId(projectRoot, env = process.env) {
|
|
37
|
+
const fromEnv = typeof env.DEFT_SESSION_ID === "string" ? env.DEFT_SESSION_ID.trim() : "";
|
|
38
|
+
if (fromEnv.length > 0) {
|
|
39
|
+
return fromEnv;
|
|
40
|
+
}
|
|
41
|
+
const [state] = readRitualState(projectRoot);
|
|
42
|
+
const id = state?.sessionId.trim() ?? "";
|
|
43
|
+
return id.length > 0 ? id : null;
|
|
44
|
+
}
|
|
32
45
|
export function isNonDeliveryDisposition(value) {
|
|
33
46
|
return (typeof value === "string" && NON_DELIVERY_DISPOSITIONS.includes(value));
|
|
34
47
|
}
|
|
@@ -162,7 +175,7 @@ export function verifyDeliveryAncestry(projectRoot, mergeCommit, deliveryBranch,
|
|
|
162
175
|
return {
|
|
163
176
|
ok: false,
|
|
164
177
|
error: `merge commit ${mergeCommit} is not an ancestor of refreshed remote delivery ref ` +
|
|
165
|
-
`${refresh.remoteRef} (${remoteTip})
|
|
178
|
+
`${refresh.remoteRef} (${remoteTip}).`,
|
|
166
179
|
remoteTip,
|
|
167
180
|
};
|
|
168
181
|
}
|
|
@@ -186,14 +199,21 @@ function buildProvenance(input) {
|
|
|
186
199
|
uatVerified: e.uatVerified ?? null,
|
|
187
200
|
};
|
|
188
201
|
}
|
|
202
|
+
function deliveryEvidenceRemediation(deliveryBranch) {
|
|
203
|
+
return (`Pass scope:complete -- --merge-commit <sha> (and --pr <n> if you have one). ` +
|
|
204
|
+
`When develop is the real delivery target, type plan.policy.deliveryBranch ` +
|
|
205
|
+
`(task policy:show --field=deliveryBranch). ` +
|
|
206
|
+
`When ${deliveryBranch} is delivery, wait until the merge commit is an ancestor of ` +
|
|
207
|
+
`origin/${deliveryBranch}, then complete. Do not use --non-delivery for work that shipped.`);
|
|
208
|
+
}
|
|
189
209
|
/**
|
|
190
|
-
* Gate delivered completion for a code-bearing scope (#3041).
|
|
210
|
+
* Gate delivered completion for a code-bearing scope (#3041 / #3380).
|
|
191
211
|
*
|
|
192
212
|
* Returns ok=true with provenance when:
|
|
193
213
|
* - scope is not code-bearing (provenance may be null or non-code note), OR
|
|
194
214
|
* - explicit non-delivery disposition is provided, OR
|
|
195
|
-
* -
|
|
196
|
-
*
|
|
215
|
+
* - merge commit is an ancestor of the refreshed remote delivery ref (prBase is
|
|
216
|
+
* provenance only; it need not equal deliveryBranch).
|
|
197
217
|
*/
|
|
198
218
|
export function evaluateDeliveryGate(options) {
|
|
199
219
|
const runGit = options.runGit ?? defaultGitRunner;
|
|
@@ -254,10 +274,8 @@ export function evaluateDeliveryGate(options) {
|
|
|
254
274
|
return {
|
|
255
275
|
ok: false,
|
|
256
276
|
message: `Delivery evidence required for code-bearing scope completion (#3041). ` +
|
|
257
|
-
`
|
|
258
|
-
`
|
|
259
|
-
`(${NON_DELIVERY_DISPOSITIONS.join("|")}). ` +
|
|
260
|
-
`Merged-to-integration alone is not delivery.`,
|
|
277
|
+
`A merge commit that is an ancestor of refreshed origin/${deliveryBranch} is delivery; ` +
|
|
278
|
+
`PR base is provenance only. ${deliveryEvidenceRemediation(deliveryBranch)}`,
|
|
261
279
|
provenance: null,
|
|
262
280
|
codeBearing: true,
|
|
263
281
|
};
|
|
@@ -281,27 +299,11 @@ export function evaluateDeliveryGate(options) {
|
|
|
281
299
|
};
|
|
282
300
|
}
|
|
283
301
|
}
|
|
284
|
-
if (prBase !== null && prBase !== deliveryBranch) {
|
|
285
|
-
const provenance = buildProvenance({
|
|
286
|
-
evidence,
|
|
287
|
-
deliveryBranch,
|
|
288
|
-
disposition: "merged_to_integration",
|
|
289
|
-
handoffState: "merged_to_integration",
|
|
290
|
-
nowIso: options.nowIso,
|
|
291
|
-
verifier,
|
|
292
|
-
});
|
|
293
|
-
return {
|
|
294
|
-
ok: false,
|
|
295
|
-
message: `PR base '${prBase}' is not the configured delivery branch '${deliveryBranch}'. ` +
|
|
296
|
-
`A merge into an intermediate/feature/integration branch is not delivery evidence (#3041).`,
|
|
297
|
-
provenance,
|
|
298
|
-
codeBearing: true,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
302
|
if (mergeCommit === null) {
|
|
302
303
|
return {
|
|
303
304
|
ok: false,
|
|
304
|
-
message: "Delivery evidence missing merge_commit_sha; cannot prove ancestry on delivery branch (#3041)."
|
|
305
|
+
message: "Delivery evidence missing merge_commit_sha; cannot prove ancestry on delivery branch (#3041). " +
|
|
306
|
+
deliveryEvidenceRemediation(deliveryBranch),
|
|
305
307
|
provenance: null,
|
|
306
308
|
codeBearing: true,
|
|
307
309
|
};
|
|
@@ -326,9 +328,15 @@ export function evaluateDeliveryGate(options) {
|
|
|
326
328
|
const ancestry = verifyDeliveryAncestry(options.projectRoot, mergeCommit, deliveryBranch, runGit);
|
|
327
329
|
if (!ancestry.ok) {
|
|
328
330
|
const integrationOnly = prBase !== null && prBase !== deliveryBranch;
|
|
331
|
+
const ancestryMsg = ancestry.error ?? "delivery ancestry check failed";
|
|
332
|
+
const rem = deliveryEvidenceRemediation(deliveryBranch);
|
|
333
|
+
const message = integrationOnly
|
|
334
|
+
? `${ancestryMsg} PR base '${prBase}' is provenance only; ` +
|
|
335
|
+
`the merge is not yet on origin/${deliveryBranch}. ${rem}`
|
|
336
|
+
: `${ancestryMsg} ${rem}`;
|
|
329
337
|
return {
|
|
330
338
|
ok: false,
|
|
331
|
-
message
|
|
339
|
+
message,
|
|
332
340
|
provenance: buildProvenance({
|
|
333
341
|
evidence,
|
|
334
342
|
deliveryBranch,
|
|
@@ -380,6 +388,10 @@ export function stampDeliveryProvenance(plan, provenance) {
|
|
|
380
388
|
// Deploy/UAT are explicit-only; default null so readers never infer from Git.
|
|
381
389
|
deployed: provenance.deployed,
|
|
382
390
|
uatVerified: provenance.uatVerified,
|
|
391
|
+
...(typeof provenance.completedSessionId === "string" &&
|
|
392
|
+
provenance.completedSessionId.trim().length > 0
|
|
393
|
+
? { completedSessionId: provenance.completedSessionId.trim() }
|
|
394
|
+
: {}),
|
|
383
395
|
};
|
|
384
396
|
meta.deliveryDisposition = provenance.disposition;
|
|
385
397
|
meta.handoffState = provenance.handoffState;
|
package/dist/scope/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from "./main.js";
|
|
|
12
12
|
export * from "./open-umbrella-warning.js";
|
|
13
13
|
export * from "./parent-lineage.js";
|
|
14
14
|
export * from "./project-context.js";
|
|
15
|
+
export * from "./project-invariant-coverage.js";
|
|
15
16
|
export * from "./promote-from-issue.js";
|
|
16
17
|
export * from "./promote-path.js";
|
|
17
18
|
export * from "./transition.js";
|
package/dist/scope/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from "./main.js";
|
|
|
12
12
|
export * from "./open-umbrella-warning.js";
|
|
13
13
|
export * from "./parent-lineage.js";
|
|
14
14
|
export * from "./project-context.js";
|
|
15
|
+
export * from "./project-invariant-coverage.js";
|
|
15
16
|
export * from "./promote-from-issue.js";
|
|
16
17
|
export * from "./promote-path.js";
|
|
17
18
|
export * from "./transition.js";
|
|
@@ -98,20 +98,21 @@ export function extractChildCoverageDraft(child) {
|
|
|
98
98
|
candidates.push({ source: "plan", obj: plan });
|
|
99
99
|
candidates.push({ source: "root", obj: root });
|
|
100
100
|
for (const c of candidates) {
|
|
101
|
+
const nestedCoverage = asRecord(c.obj.coverage);
|
|
101
102
|
const hasMap = "coverage_map" in c.obj ||
|
|
102
103
|
"coverageMap" in c.obj ||
|
|
103
|
-
|
|
104
|
+
nestedCoverage?.coverage_map !== undefined ||
|
|
105
|
+
nestedCoverage?.coverageMap !== undefined;
|
|
104
106
|
if (!hasMap)
|
|
105
107
|
continue;
|
|
106
|
-
const coverageNested = asRecord(c.obj.coverage);
|
|
107
108
|
const coverage_map = c.obj.coverage_map ??
|
|
108
109
|
c.obj.coverageMap ??
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
nestedCoverage?.coverage_map ??
|
|
111
|
+
nestedCoverage?.coverageMap;
|
|
111
112
|
const behavioral_deltas = c.obj.behavioral_deltas ??
|
|
112
113
|
c.obj.behavioralDeltas ??
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
nestedCoverage?.behavioral_deltas ??
|
|
115
|
+
nestedCoverage?.behavioralDeltas;
|
|
115
116
|
return {
|
|
116
117
|
draft: {
|
|
117
118
|
coverage_map,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project-invariant coverage + applicability (#3425 Story A).
|
|
3
|
+
*
|
|
4
|
+
* Reuses the #3238 coverage_map parser and side-field rules. `split` is
|
|
5
|
+
* excluded at project level. Optional `not_applicable` requires a reason.
|
|
6
|
+
* Applicability is a pure intersection of contract surface × file_scope.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProjectInvariant } from "../policy/project-invariants.js";
|
|
9
|
+
export declare const PROJECT_INVARIANT_DISPOSITIONS: readonly ["covered", "deferred", "behavioral_delta", "not_applicable"];
|
|
10
|
+
export type ProjectInvariantDisposition = (typeof PROJECT_INVARIANT_DISPOSITIONS)[number];
|
|
11
|
+
export interface ApplicableInvariant {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly reason: "path" | "module" | "unresolved-module";
|
|
14
|
+
}
|
|
15
|
+
export interface ProjectInvariantCoverageResult {
|
|
16
|
+
readonly ok: boolean;
|
|
17
|
+
readonly applicableIds: readonly string[];
|
|
18
|
+
readonly missingIds: readonly string[];
|
|
19
|
+
readonly errors: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
export type GlobDepth = "exact" | "one" | "subtree";
|
|
22
|
+
export interface ClassifiedGlob {
|
|
23
|
+
readonly prefix: string;
|
|
24
|
+
readonly depth: GlobDepth;
|
|
25
|
+
readonly leadingDoubleStar: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Classify a path/glob without regular expressions (CodeQL js/polynomial-redos).
|
|
29
|
+
* Unstarred paths are directory prefixes (file_scope semantics).
|
|
30
|
+
*/
|
|
31
|
+
export declare function classifyGlob(glob: string): ClassifiedGlob;
|
|
32
|
+
/** Strip glob tails so prefix comparison stays path-shaped. */
|
|
33
|
+
export declare function normalizeGlobAsPath(glob: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* True when two path/glob strings can name a shared tree.
|
|
36
|
+
* `/*` is one segment; `/**` / unstarred file_scope paths are subtrees.
|
|
37
|
+
*/
|
|
38
|
+
export declare function pathGlobsIntersect(left: string, right: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Invariants whose contract surface intersects `fileScope`.
|
|
41
|
+
* Empty file_scope → empty intersection (no disposition required).
|
|
42
|
+
* Unresolved module ids (no pathGlobs mapping) are treated as applicable.
|
|
43
|
+
*/
|
|
44
|
+
export declare function applicableProjectInvariants(invariants: readonly ProjectInvariant[], fileScope: readonly string[], modulePathGlobs?: Readonly<Record<string, readonly string[]>>): ApplicableInvariant[];
|
|
45
|
+
/**
|
|
46
|
+
* Completeness of coverage_map dispositions for applicable project invariant IDs.
|
|
47
|
+
* Extra coverage_map keys (e.g. parent requirement IDs) are ignored.
|
|
48
|
+
* Empty applicable set is a no-op success.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateProjectInvariantCoverage(opts: {
|
|
51
|
+
applicableIds: readonly string[];
|
|
52
|
+
draft: unknown;
|
|
53
|
+
}): ProjectInvariantCoverageResult;
|
|
54
|
+
//# sourceMappingURL=project-invariant-coverage.d.ts.map
|