@deftai/directive-core 0.104.0 → 0.106.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 +1108 -67
- 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 +34 -4
- 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/forward-coverage/diff-coverage.d.ts +39 -0
- package/dist/forward-coverage/diff-coverage.js +112 -0
- package/dist/forward-coverage/diff-lines.d.ts +19 -0
- package/dist/forward-coverage/diff-lines.js +173 -0
- package/dist/forward-coverage/evaluate.d.ts +24 -9
- package/dist/forward-coverage/evaluate.js +125 -19
- 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.d.ts +1 -1
- package/dist/init-deposit/agent-hooks.js +18 -16
- 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 +47 -1
- package/dist/intake/clause-derivation.js +238 -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/lifecycle-visible/evaluate.d.ts +98 -0
- package/dist/lifecycle-visible/evaluate.js +710 -0
- package/dist/lifecycle-visible/index.d.ts +2 -0
- package/dist/lifecycle-visible/index.js +2 -0
- package/dist/literal-acceptance/capture.d.ts +10 -0
- package/dist/literal-acceptance/capture.js +226 -77
- 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/orchestration/judgment-policy.d.ts +13 -0
- package/dist/orchestration/judgment-policy.js +15 -0
- package/dist/orchestration/probe-session.js +13 -8
- package/dist/orchestration/verify-judgment-gates.d.ts +4 -0
- package/dist/orchestration/verify-judgment-gates.js +43 -11
- 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 +11 -21
- 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/host-hooks.d.ts +20 -0
- package/dist/policy/host-hooks.js +121 -2
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.js +66 -7
- package/dist/policy/org-force-on-migration.js +2 -1
- package/dist/policy/plan-extensions.d.ts +1 -1
- package/dist/policy/plan-extensions.js +2 -0
- package/dist/policy/product-signal.js +6 -7
- package/dist/policy/project-invariants.d.ts +50 -0
- package/dist/policy/project-invariants.js +205 -0
- package/dist/policy/require-human-merge.js +8 -6
- package/dist/policy/resolve.d.ts +7 -2
- package/dist/policy/resolve.js +25 -8
- 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/policy/value-feedback.js +7 -8
- 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/preflight-cache/evaluate.d.ts +12 -0
- package/dist/preflight-cache/evaluate.js +15 -1
- package/dist/preflight-cache/index.d.ts +1 -1
- package/dist/preflight-cache/index.js +1 -1
- 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 +16 -0
- package/dist/product-first-done-gate/evaluate.js +298 -34
- 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/release/closed-verb-gate.d.ts +12 -0
- package/dist/release/closed-verb-gate.js +51 -0
- package/dist/release/index.d.ts +1 -0
- package/dist/release/index.js +1 -0
- package/dist/release/pipeline.js +7 -0
- package/dist/release/types.d.ts +12 -0
- package/dist/render/constants.d.ts +2 -1
- package/dist/render/constants.js +2 -1
- package/dist/render/framework-commands.js +4 -0
- package/dist/render/spec-validate.js +23 -12
- 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 +33 -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/main.js +15 -5
- 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/promote-from-issue.js +5 -5
- 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 +67 -7
- 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 +9 -36
- package/dist/session/ac-pass-banking.js +33 -79
- 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/process-cost.d.ts +32 -10
- package/dist/session/process-cost.js +189 -1
- package/dist/session/product-state-hash.d.ts +26 -0
- package/dist/session/product-state-hash.js +700 -0
- package/dist/session/ritual-entrypoint.js +16 -1
- package/dist/session/session-ready.d.ts +2 -0
- package/dist/session/session-ready.js +52 -30
- package/dist/session/session-start.d.ts +13 -0
- package/dist/session/session-start.js +103 -9
- 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 +28 -0
- package/dist/session/verify-session-ritual.js +97 -5
- 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-cli.d.ts +7 -2
- package/dist/swarm/finalize-cohort-cli.js +165 -35
- package/dist/swarm/finalize-cohort.d.ts +1 -0
- package/dist/swarm/finalize-cohort.js +47 -4
- 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 +15 -3
- package/dist/swarm/routing-verify.d.ts +13 -1
- package/dist/swarm/routing-verify.js +60 -21
- 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/triage/bootstrap/index.js +6 -6
- package/dist/triage/help/registry-data.d.ts +1 -1
- package/dist/triage/help/registry-data.js +1 -1
- package/dist/triage/welcome/writers.d.ts +1 -1
- package/dist/triage/welcome/writers.js +10 -5
- 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/value/readback.d.ts +4 -1
- package/dist/value/readback.js +51 -12
- 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/vbrief-validate/schema.d.ts +4 -0
- package/dist/vbrief-validate/schema.js +1 -1
- 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-env/agent-hook-readiness.d.ts +2 -2
- package/dist/verify-env/agent-hook-readiness.js +12 -8
- package/dist/verify-env/agent-hooks-live-probe.d.ts +5 -1
- package/dist/verify-env/agent-hooks-live-probe.js +26 -5
- package/dist/verify-env/agent-hooks.js +3 -4
- 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 +7 -3
|
@@ -72,10 +72,9 @@ export function classifyIdentityKind(options) {
|
|
|
72
72
|
function isCloudHeadless(environ) {
|
|
73
73
|
if (envTruthy(environ, "CURSOR_AGENT"))
|
|
74
74
|
return true;
|
|
75
|
-
|
|
76
|
-
return true;
|
|
75
|
+
// GROK_BUILD / DEFT_AGENT_RUNTIME=grok-build identify a local TUI, not CI (#3469).
|
|
77
76
|
const runtime = (environ.DEFT_AGENT_RUNTIME ?? "").trim().toLowerCase();
|
|
78
|
-
if (runtime === "
|
|
77
|
+
if (runtime === "cloud" || runtime === "headless")
|
|
79
78
|
return true;
|
|
80
79
|
if (envTruthy(environ, "GITHUB_ACTIONS") || envTruthy(environ, "BUILDKITE"))
|
|
81
80
|
return true;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed plan.policy.baseBranch (#3388).
|
|
3
|
+
*
|
|
4
|
+
* Integration-branch source for the shared branch-sync detector. Distinct from
|
|
5
|
+
* deliveryBranch (dest). Unset or invalid baseBranch resolves to dest so sync
|
|
6
|
+
* is a no-op. origin/develop is never identity; it may only emit a hint.
|
|
7
|
+
*/
|
|
8
|
+
import { type GitRunner } from "../session/git.js";
|
|
9
|
+
export declare const FIELD_BASE_BRANCH = "plan.policy.baseBranch";
|
|
10
|
+
export declare const FIELD_BASE_BRANCH_CLI_ALIAS = "baseBranch";
|
|
11
|
+
/** Nudge only — never used as dest or source identity (#3388 / #3377 Q1). */
|
|
12
|
+
export declare const ORIGIN_DEVELOP_HINT = "origin/develop exists; set plan.policy.baseBranch if this repo uses an integration branch";
|
|
13
|
+
export type BaseBranchSource = "typed" | "equals-dest" | "default-on-error";
|
|
14
|
+
export interface BaseBranchResult {
|
|
15
|
+
readonly branch: string;
|
|
16
|
+
readonly dest: string;
|
|
17
|
+
readonly source: BaseBranchSource;
|
|
18
|
+
readonly typed: boolean;
|
|
19
|
+
readonly error: string | null;
|
|
20
|
+
readonly developHint: string | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve plan.policy.baseBranch (#3388).
|
|
24
|
+
*
|
|
25
|
+
* Unset or invalid values equal dest (deliveryBranch). origin/develop is never
|
|
26
|
+
* substituted as the source.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveBaseBranch(projectRoot: string, runGit?: GitRunner): BaseBranchResult;
|
|
29
|
+
export interface BaseBranchPolicyField {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly current: string;
|
|
32
|
+
readonly default: string;
|
|
33
|
+
readonly source: string;
|
|
34
|
+
}
|
|
35
|
+
/** Inspector row for `task policy:show --field=baseBranch` (#3388). */
|
|
36
|
+
export declare function inspectBaseBranch(_data: Record<string, unknown> | null, projectRoot?: string): BaseBranchPolicyField;
|
|
37
|
+
//# sourceMappingURL=base-branch.d.ts.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed plan.policy.baseBranch (#3388).
|
|
3
|
+
*
|
|
4
|
+
* Integration-branch source for the shared branch-sync detector. Distinct from
|
|
5
|
+
* deliveryBranch (dest). Unset or invalid baseBranch resolves to dest so sync
|
|
6
|
+
* is a no-op. origin/develop is never identity; it may only emit a hint.
|
|
7
|
+
*/
|
|
8
|
+
import { defaultGitRunner } from "../session/git.js";
|
|
9
|
+
import { DEFAULT_DELIVERY_BRANCH_FALLBACK, resolveDeliveryBranch } from "./delivery-branch.js";
|
|
10
|
+
import { readPlanPolicy } from "./plan-extensions.js";
|
|
11
|
+
import { loadProjectDefinition } from "./resolve.js";
|
|
12
|
+
export const FIELD_BASE_BRANCH = "plan.policy.baseBranch";
|
|
13
|
+
export const FIELD_BASE_BRANCH_CLI_ALIAS = "baseBranch";
|
|
14
|
+
/** Nudge only — never used as dest or source identity (#3388 / #3377 Q1). */
|
|
15
|
+
export const ORIGIN_DEVELOP_HINT = "origin/develop exists; set plan.policy.baseBranch if this repo uses an integration branch";
|
|
16
|
+
function originRefExists(projectRoot, branch, runGit) {
|
|
17
|
+
const check = runGit(projectRoot, [
|
|
18
|
+
"show-ref",
|
|
19
|
+
"--verify",
|
|
20
|
+
"--quiet",
|
|
21
|
+
`refs/remotes/origin/${branch}`,
|
|
22
|
+
]);
|
|
23
|
+
return check.code === 0;
|
|
24
|
+
}
|
|
25
|
+
function developHintIfEligible(projectRoot, typed, runGit) {
|
|
26
|
+
if (typed)
|
|
27
|
+
return null;
|
|
28
|
+
if (!originRefExists(projectRoot, "develop", runGit))
|
|
29
|
+
return null;
|
|
30
|
+
return ORIGIN_DEVELOP_HINT;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Resolve plan.policy.baseBranch (#3388).
|
|
34
|
+
*
|
|
35
|
+
* Unset or invalid values equal dest (deliveryBranch). origin/develop is never
|
|
36
|
+
* substituted as the source.
|
|
37
|
+
*/
|
|
38
|
+
export function resolveBaseBranch(projectRoot, runGit = defaultGitRunner) {
|
|
39
|
+
const dest = resolveDeliveryBranch(projectRoot, runGit).branch || DEFAULT_DELIVERY_BRANCH_FALLBACK;
|
|
40
|
+
const [data, err] = loadProjectDefinition(projectRoot);
|
|
41
|
+
if (data === null) {
|
|
42
|
+
return {
|
|
43
|
+
branch: dest,
|
|
44
|
+
dest,
|
|
45
|
+
source: "equals-dest",
|
|
46
|
+
typed: false,
|
|
47
|
+
error: err,
|
|
48
|
+
developHint: developHintIfEligible(projectRoot, false, runGit),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const plan = data.plan;
|
|
52
|
+
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
53
|
+
return {
|
|
54
|
+
branch: dest,
|
|
55
|
+
dest,
|
|
56
|
+
source: "equals-dest",
|
|
57
|
+
typed: false,
|
|
58
|
+
error: "PROJECT-DEFINITION 'plan' is not an object",
|
|
59
|
+
developHint: developHintIfEligible(projectRoot, false, runGit),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const policyBlock = readPlanPolicy(plan);
|
|
63
|
+
if (typeof policyBlock === "object" &&
|
|
64
|
+
policyBlock !== null &&
|
|
65
|
+
!Array.isArray(policyBlock) &&
|
|
66
|
+
"baseBranch" in policyBlock) {
|
|
67
|
+
const raw = policyBlock.baseBranch;
|
|
68
|
+
if (typeof raw !== "string" || raw.trim().length === 0) {
|
|
69
|
+
return {
|
|
70
|
+
branch: dest,
|
|
71
|
+
dest,
|
|
72
|
+
source: "default-on-error",
|
|
73
|
+
typed: false,
|
|
74
|
+
error: `plan.policy.baseBranch must be a non-empty string; got ${typeof raw}`,
|
|
75
|
+
developHint: developHintIfEligible(projectRoot, false, runGit),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
branch: raw.trim(),
|
|
80
|
+
dest,
|
|
81
|
+
source: "typed",
|
|
82
|
+
typed: true,
|
|
83
|
+
error: null,
|
|
84
|
+
developHint: null,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
branch: dest,
|
|
89
|
+
dest,
|
|
90
|
+
source: "equals-dest",
|
|
91
|
+
typed: false,
|
|
92
|
+
error: null,
|
|
93
|
+
developHint: developHintIfEligible(projectRoot, false, runGit),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Inspector row for `task policy:show --field=baseBranch` (#3388). */
|
|
97
|
+
export function inspectBaseBranch(_data, projectRoot) {
|
|
98
|
+
if (projectRoot === undefined || projectRoot.length === 0) {
|
|
99
|
+
return {
|
|
100
|
+
name: FIELD_BASE_BRANCH,
|
|
101
|
+
current: DEFAULT_DELIVERY_BRANCH_FALLBACK,
|
|
102
|
+
default: DEFAULT_DELIVERY_BRANCH_FALLBACK,
|
|
103
|
+
source: "equals-dest",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const resolved = resolveBaseBranch(projectRoot);
|
|
107
|
+
return {
|
|
108
|
+
name: FIELD_BASE_BRANCH,
|
|
109
|
+
current: resolved.branch,
|
|
110
|
+
default: resolved.dest,
|
|
111
|
+
source: resolved.source,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=base-branch.js.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared branch-sync detector (#3388 / #3377 Wave 1).
|
|
3
|
+
*
|
|
4
|
+
* Dest = deliveryBranch. Source = typed baseBranch (unset equals dest → not a
|
|
5
|
+
* sync). Predicate: PR base is dest AND head is already on origin/<source>
|
|
6
|
+
* after fetch (tip or ancestor). Name-only and label-only exemptions are not
|
|
7
|
+
* implemented. origin/develop is never load-bearing identity.
|
|
8
|
+
*
|
|
9
|
+
* This module is the only is-this-a-sync source for later children (#3390/#3391)
|
|
10
|
+
* and for core-guard.
|
|
11
|
+
*/
|
|
12
|
+
import { type GitRunner } from "../session/git.js";
|
|
13
|
+
/** Dest-ref blob used for dest/source. Never the PR working tree (#3388 P1). */
|
|
14
|
+
export declare const BRANCH_SYNC_POLICY_BLOB = "xbrief/PROJECT-DEFINITION.xbrief.json";
|
|
15
|
+
export declare const BRANCH_SYNC_EXEMPTION_PREFIX = "sync PR detected: all commits already guard-checked on";
|
|
16
|
+
export type BranchSyncReason = "source-equals-dest" | "base-is-not-dest" | "fetch-failed" | "head-not-on-integration" | "sync";
|
|
17
|
+
export interface BranchSyncDetection {
|
|
18
|
+
readonly isSync: boolean;
|
|
19
|
+
readonly dest: string;
|
|
20
|
+
readonly source: string;
|
|
21
|
+
readonly sourceTyped: boolean;
|
|
22
|
+
readonly reason: BranchSyncReason;
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly developHint: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface DetectBranchSyncInput {
|
|
27
|
+
readonly dest: string;
|
|
28
|
+
readonly source: string;
|
|
29
|
+
readonly sourceTyped: boolean;
|
|
30
|
+
readonly prBase: string;
|
|
31
|
+
readonly headSha: string;
|
|
32
|
+
readonly projectRoot: string;
|
|
33
|
+
readonly developHint?: string | null;
|
|
34
|
+
readonly runGit?: GitRunner;
|
|
35
|
+
}
|
|
36
|
+
export declare function formatBranchSyncExemptionMessage(integrationBranch: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Evidence-based sync predicate (#3388 Q3). Fetch first. Do not trust PR
|
|
39
|
+
* branch names or labels.
|
|
40
|
+
*/
|
|
41
|
+
export declare function detectBranchSync(input: DetectBranchSyncInput): BranchSyncDetection;
|
|
42
|
+
export interface DestRefSyncPolicy {
|
|
43
|
+
readonly dest: string;
|
|
44
|
+
readonly source: string;
|
|
45
|
+
readonly sourceTyped: boolean;
|
|
46
|
+
readonly developHint: string | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Load dest/source from origin/<prBase>, not the PR checkout.
|
|
50
|
+
*
|
|
51
|
+
* A feature PR that rewrites working-tree baseBranch cannot become a sync.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveSyncPolicyFromDestRef(options: {
|
|
54
|
+
readonly projectRoot: string;
|
|
55
|
+
readonly prBase: string;
|
|
56
|
+
readonly runGit?: GitRunner;
|
|
57
|
+
}): DestRefSyncPolicy;
|
|
58
|
+
/** Load dest/source from dest-ref policy, then run {@link detectBranchSync}. */
|
|
59
|
+
export declare function detectBranchSyncFromProject(options: {
|
|
60
|
+
readonly projectRoot: string;
|
|
61
|
+
readonly prBase: string;
|
|
62
|
+
readonly headSha: string;
|
|
63
|
+
readonly runGit?: GitRunner;
|
|
64
|
+
}): BranchSyncDetection;
|
|
65
|
+
export interface CoreGuardSyncExemption {
|
|
66
|
+
readonly wouldFail: boolean;
|
|
67
|
+
readonly loudMessage: string | null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Core-guard mix result after the shared sync predicate. Sync PRs pass
|
|
71
|
+
* loudly; mixed feature PRs still fail.
|
|
72
|
+
*/
|
|
73
|
+
export declare function applyCoreGuardWithBranchSync(classification: {
|
|
74
|
+
readonly wouldFail: boolean;
|
|
75
|
+
}, sync: BranchSyncDetection): CoreGuardSyncExemption;
|
|
76
|
+
/** Compact Python body for the deposited deft-core-guard (#3388). */
|
|
77
|
+
export declare function coreGuardBranchSyncPythonBody(): readonly string[];
|
|
78
|
+
/** Indented `if` block: detector success exits 0 (loud print); else fall through. */
|
|
79
|
+
export declare function renderCoreGuardBranchSyncIfBlock(indent: string): string;
|
|
80
|
+
//# sourceMappingURL=branch-sync.d.ts.map
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared branch-sync detector (#3388 / #3377 Wave 1).
|
|
3
|
+
*
|
|
4
|
+
* Dest = deliveryBranch. Source = typed baseBranch (unset equals dest → not a
|
|
5
|
+
* sync). Predicate: PR base is dest AND head is already on origin/<source>
|
|
6
|
+
* after fetch (tip or ancestor). Name-only and label-only exemptions are not
|
|
7
|
+
* implemented. origin/develop is never load-bearing identity.
|
|
8
|
+
*
|
|
9
|
+
* This module is the only is-this-a-sync source for later children (#3390/#3391)
|
|
10
|
+
* and for core-guard.
|
|
11
|
+
*/
|
|
12
|
+
import { defaultGitRunner, gitIsAncestor } from "../session/git.js";
|
|
13
|
+
import { ORIGIN_DEVELOP_HINT } from "./base-branch.js";
|
|
14
|
+
import { resolveGitDefaultDeliveryBranch } from "./delivery-branch.js";
|
|
15
|
+
import { readPlanPolicy } from "./plan-extensions.js";
|
|
16
|
+
/** Dest-ref blob used for dest/source. Never the PR working tree (#3388 P1). */
|
|
17
|
+
export const BRANCH_SYNC_POLICY_BLOB = "xbrief/PROJECT-DEFINITION.xbrief.json";
|
|
18
|
+
export const BRANCH_SYNC_EXEMPTION_PREFIX = "sync PR detected: all commits already guard-checked on";
|
|
19
|
+
export function formatBranchSyncExemptionMessage(integrationBranch) {
|
|
20
|
+
return `${BRANCH_SYNC_EXEMPTION_PREFIX} ${integrationBranch}`;
|
|
21
|
+
}
|
|
22
|
+
function notSync(input, reason) {
|
|
23
|
+
return {
|
|
24
|
+
isSync: false,
|
|
25
|
+
dest: input.dest,
|
|
26
|
+
source: input.source,
|
|
27
|
+
sourceTyped: input.sourceTyped,
|
|
28
|
+
reason,
|
|
29
|
+
message: "",
|
|
30
|
+
developHint: input.developHint ?? null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Evidence-based sync predicate (#3388 Q3). Fetch first. Do not trust PR
|
|
35
|
+
* branch names or labels.
|
|
36
|
+
*/
|
|
37
|
+
export function detectBranchSync(input) {
|
|
38
|
+
const dest = input.dest.trim();
|
|
39
|
+
const source = input.source.trim();
|
|
40
|
+
if (source.length === 0 || dest.length === 0 || source === dest) {
|
|
41
|
+
return notSync({ ...input, dest, source }, "source-equals-dest");
|
|
42
|
+
}
|
|
43
|
+
if (input.prBase.trim() !== dest) {
|
|
44
|
+
return notSync({ ...input, dest, source }, "base-is-not-dest");
|
|
45
|
+
}
|
|
46
|
+
const runGit = input.runGit ?? defaultGitRunner;
|
|
47
|
+
const fetched = runGit(input.projectRoot, ["fetch", "--quiet", "origin", source]);
|
|
48
|
+
if (fetched.code !== 0) {
|
|
49
|
+
return notSync({ ...input, dest, source }, "fetch-failed");
|
|
50
|
+
}
|
|
51
|
+
const onIntegration = gitIsAncestor(input.projectRoot, input.headSha, `origin/${source}`, runGit);
|
|
52
|
+
if (onIntegration !== true) {
|
|
53
|
+
return notSync({ ...input, dest, source }, "head-not-on-integration");
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
isSync: true,
|
|
57
|
+
dest,
|
|
58
|
+
source,
|
|
59
|
+
sourceTyped: input.sourceTyped,
|
|
60
|
+
reason: "sync",
|
|
61
|
+
message: formatBranchSyncExemptionMessage(source),
|
|
62
|
+
developHint: input.developHint ?? null,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function parseTypedPolicyBranches(jsonText) {
|
|
66
|
+
try {
|
|
67
|
+
const data = JSON.parse(jsonText);
|
|
68
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
69
|
+
return { dest: null, source: null };
|
|
70
|
+
}
|
|
71
|
+
const policyBlock = readPlanPolicy(data.plan);
|
|
72
|
+
if (typeof policyBlock !== "object" || policyBlock === null || Array.isArray(policyBlock)) {
|
|
73
|
+
return { dest: null, source: null };
|
|
74
|
+
}
|
|
75
|
+
const rec = policyBlock;
|
|
76
|
+
const destRaw = rec.deliveryBranch;
|
|
77
|
+
const sourceRaw = rec.baseBranch;
|
|
78
|
+
return {
|
|
79
|
+
dest: typeof destRaw === "string" && destRaw.trim().length > 0 ? destRaw.trim() : null,
|
|
80
|
+
source: typeof sourceRaw === "string" && sourceRaw.trim().length > 0 ? sourceRaw.trim() : null,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return { dest: null, source: null };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Load dest/source from origin/<prBase>, not the PR checkout.
|
|
89
|
+
*
|
|
90
|
+
* A feature PR that rewrites working-tree baseBranch cannot become a sync.
|
|
91
|
+
*/
|
|
92
|
+
export function resolveSyncPolicyFromDestRef(options) {
|
|
93
|
+
const runGit = options.runGit ?? defaultGitRunner;
|
|
94
|
+
const prBase = options.prBase.trim();
|
|
95
|
+
const fetched = runGit(options.projectRoot, ["fetch", "--quiet", "origin", prBase]);
|
|
96
|
+
if (fetched.code !== 0) {
|
|
97
|
+
const dest = resolveGitDefaultDeliveryBranch(options.projectRoot, runGit);
|
|
98
|
+
const developHint = runGit(options.projectRoot, [
|
|
99
|
+
"show-ref",
|
|
100
|
+
"--verify",
|
|
101
|
+
"--quiet",
|
|
102
|
+
"refs/remotes/origin/develop",
|
|
103
|
+
]).code === 0
|
|
104
|
+
? ORIGIN_DEVELOP_HINT
|
|
105
|
+
: null;
|
|
106
|
+
return { dest, source: dest, sourceTyped: false, developHint };
|
|
107
|
+
}
|
|
108
|
+
const shown = runGit(options.projectRoot, [
|
|
109
|
+
"show",
|
|
110
|
+
`origin/${prBase}:${BRANCH_SYNC_POLICY_BLOB}`,
|
|
111
|
+
]);
|
|
112
|
+
const parsed = shown.code === 0 && shown.stdout.length > 0
|
|
113
|
+
? parseTypedPolicyBranches(shown.stdout)
|
|
114
|
+
: { dest: null, source: null };
|
|
115
|
+
const dest = parsed.dest ?? resolveGitDefaultDeliveryBranch(options.projectRoot, runGit);
|
|
116
|
+
const sourceTyped = parsed.source !== null;
|
|
117
|
+
const source = parsed.source ?? dest;
|
|
118
|
+
const developHint = sourceTyped ||
|
|
119
|
+
runGit(options.projectRoot, ["show-ref", "--verify", "--quiet", "refs/remotes/origin/develop"])
|
|
120
|
+
.code !== 0
|
|
121
|
+
? null
|
|
122
|
+
: ORIGIN_DEVELOP_HINT;
|
|
123
|
+
return { dest, source, sourceTyped, developHint };
|
|
124
|
+
}
|
|
125
|
+
/** Load dest/source from dest-ref policy, then run {@link detectBranchSync}. */
|
|
126
|
+
export function detectBranchSyncFromProject(options) {
|
|
127
|
+
const runGit = options.runGit ?? defaultGitRunner;
|
|
128
|
+
const policy = resolveSyncPolicyFromDestRef({
|
|
129
|
+
projectRoot: options.projectRoot,
|
|
130
|
+
prBase: options.prBase,
|
|
131
|
+
runGit,
|
|
132
|
+
});
|
|
133
|
+
return detectBranchSync({
|
|
134
|
+
dest: policy.dest,
|
|
135
|
+
source: policy.source,
|
|
136
|
+
sourceTyped: policy.sourceTyped,
|
|
137
|
+
prBase: options.prBase,
|
|
138
|
+
headSha: options.headSha,
|
|
139
|
+
projectRoot: options.projectRoot,
|
|
140
|
+
developHint: policy.developHint,
|
|
141
|
+
runGit,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Core-guard mix result after the shared sync predicate. Sync PRs pass
|
|
146
|
+
* loudly; mixed feature PRs still fail.
|
|
147
|
+
*/
|
|
148
|
+
export function applyCoreGuardWithBranchSync(classification, sync) {
|
|
149
|
+
if (!classification.wouldFail) {
|
|
150
|
+
return { wouldFail: false, loudMessage: null };
|
|
151
|
+
}
|
|
152
|
+
if (sync.isSync) {
|
|
153
|
+
return { wouldFail: false, loudMessage: formatBranchSyncExemptionMessage(sync.source) };
|
|
154
|
+
}
|
|
155
|
+
return { wouldFail: true, loudMessage: null };
|
|
156
|
+
}
|
|
157
|
+
/** Compact Python body for the deposited deft-core-guard (#3388). */
|
|
158
|
+
export function coreGuardBranchSyncPythonBody() {
|
|
159
|
+
return [
|
|
160
|
+
"import json, subprocess, sys",
|
|
161
|
+
"head_sha, pr_base = sys.argv[1], sys.argv[2]",
|
|
162
|
+
"def git(*a):",
|
|
163
|
+
" return subprocess.run(['git', *a], capture_output=True, text=True)",
|
|
164
|
+
"dest = source = None",
|
|
165
|
+
"if git('fetch', '--quiet', 'origin', pr_base).returncode != 0: sys.exit(1)",
|
|
166
|
+
`shown = git('show', 'origin/' + pr_base + ':${BRANCH_SYNC_POLICY_BLOB}')`,
|
|
167
|
+
"if shown.returncode == 0:",
|
|
168
|
+
" try:",
|
|
169
|
+
" plan = json.loads(shown.stdout).get('plan')",
|
|
170
|
+
" except Exception:",
|
|
171
|
+
" plan = None",
|
|
172
|
+
" if isinstance(plan, dict):",
|
|
173
|
+
" pol = plan.get('x-directive/policy') or plan.get('policy') or {}",
|
|
174
|
+
" if isinstance(pol, dict):",
|
|
175
|
+
" d, s = pol.get('deliveryBranch'), pol.get('baseBranch')",
|
|
176
|
+
" if isinstance(d, str) and d.strip(): dest = d.strip()",
|
|
177
|
+
" if isinstance(s, str) and s.strip(): source = s.strip()",
|
|
178
|
+
"if not dest:",
|
|
179
|
+
" r = git('symbolic-ref', 'refs/remotes/origin/HEAD', '--short')",
|
|
180
|
+
" if r.returncode == 0 and r.stdout.strip():",
|
|
181
|
+
" dest = r.stdout.strip().split('/', 1)[-1]",
|
|
182
|
+
" else:",
|
|
183
|
+
" for n in ('main', 'master'):",
|
|
184
|
+
" if git('show-ref', '--verify', '--quiet', 'refs/remotes/origin/' + n).returncode == 0:",
|
|
185
|
+
" dest = n",
|
|
186
|
+
" break",
|
|
187
|
+
" if not dest:",
|
|
188
|
+
" for n in ('main', 'master'):",
|
|
189
|
+
" if git('show-ref', '--verify', '--quiet', 'refs/heads/' + n).returncode == 0:",
|
|
190
|
+
" dest = n",
|
|
191
|
+
" break",
|
|
192
|
+
" if not dest: dest = 'master'",
|
|
193
|
+
"if not source: source = dest",
|
|
194
|
+
"if source == dest or pr_base != dest: sys.exit(1)",
|
|
195
|
+
"if git('fetch', '--quiet', 'origin', source).returncode != 0: sys.exit(1)",
|
|
196
|
+
"if git('merge-base', '--is-ancestor', head_sha, 'origin/' + source).returncode != 0: sys.exit(1)",
|
|
197
|
+
`print('${BRANCH_SYNC_EXEMPTION_PREFIX} ' + source)`,
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
/** Indented `if` block: detector success exits 0 (loud print); else fall through. */
|
|
201
|
+
export function renderCoreGuardBranchSyncIfBlock(indent) {
|
|
202
|
+
return [
|
|
203
|
+
`${indent}if python3 - "$HEAD_SHA" "$BASE_REF" <<'PY'`,
|
|
204
|
+
...coreGuardBranchSyncPythonBody().map((line) => `${indent}${line}`),
|
|
205
|
+
`${indent}PY`,
|
|
206
|
+
`${indent}then`,
|
|
207
|
+
`${indent} exit 0`,
|
|
208
|
+
`${indent}fi`,
|
|
209
|
+
].join("\n");
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=branch-sync.js.map
|
|
@@ -77,6 +77,7 @@ export function emitCeremonyDialEscalationEvaluation(options) {
|
|
|
77
77
|
projectRoot: options.projectRoot,
|
|
78
78
|
sessionId: options.sessionId,
|
|
79
79
|
env: options.env,
|
|
80
|
+
component: "ceremony-dial",
|
|
80
81
|
});
|
|
81
82
|
emitter.emitDialEscalationEvaluation({
|
|
82
83
|
tier: options.evaluation.tier,
|
|
@@ -23,7 +23,7 @@ import { RunSummaryEmitter } from "../run-summary/emit.js";
|
|
|
23
23
|
import { atomicWriteProjectDefinition, projectDefinitionMutationLock, } from "../vbrief-build/project-definition-io.js";
|
|
24
24
|
import { migrateLegacyPolicyKey, PLAN_POLICY_KEY, readPlanPolicy } from "./plan-extensions.js";
|
|
25
25
|
import { policyColonInvocation } from "./policy-invocation.js";
|
|
26
|
-
import { appendAuditLog, loadProjectDefinition, projectDefinitionPath } from "./resolve.js";
|
|
26
|
+
import { appendAuditLog, loadProjectDefinition, POLICY_AUDIT_NOOP_STDOUT, projectDefinitionPath, } from "./resolve.js";
|
|
27
27
|
/** Canonical dotted policy field name. */
|
|
28
28
|
export const FIELD_CEREMONY_DIAL = "plan.policy.ceremonyDial";
|
|
29
29
|
/** Short alias for `policy:show --field=ceremonyDial`. */
|
|
@@ -527,7 +527,7 @@ export function setCeremonyDial(projectRoot, options) {
|
|
|
527
527
|
}
|
|
528
528
|
}
|
|
529
529
|
const plan = data.plan;
|
|
530
|
-
migrateLegacyPolicyKey(plan);
|
|
530
|
+
const legacyKeyMigrated = migrateLegacyPolicyKey(plan);
|
|
531
531
|
const existingPolicy = plan[PLAN_POLICY_KEY];
|
|
532
532
|
if (typeof existingPolicy !== "object" ||
|
|
533
533
|
existingPolicy === null ||
|
|
@@ -564,7 +564,9 @@ export function setCeremonyDial(projectRoot, options) {
|
|
|
564
564
|
override: nextOverride,
|
|
565
565
|
};
|
|
566
566
|
const prevParsed = parseConfig(previous).config;
|
|
567
|
-
const changedFlag = prevParsed.enabled !== nextBlock.enabled ||
|
|
567
|
+
const changedFlag = prevParsed.enabled !== nextBlock.enabled ||
|
|
568
|
+
prevParsed.override !== nextBlock.override ||
|
|
569
|
+
legacyKeyMigrated;
|
|
568
570
|
policyBlock.ceremonyDial = nextBlock;
|
|
569
571
|
if (changedFlag) {
|
|
570
572
|
atomicWriteProjectDefinition(path, data);
|
|
@@ -580,15 +582,13 @@ export function setCeremonyDial(projectRoot, options) {
|
|
|
580
582
|
if (note) {
|
|
581
583
|
parts.push(`note=${note.replace(/\n/g, " ").replace(/\r/g, " ")}`);
|
|
582
584
|
}
|
|
583
|
-
appendAuditLog(projectRoot, parts.join(" "));
|
|
585
|
+
appendAuditLog(projectRoot, parts.join(" "), changedFlag);
|
|
584
586
|
return { changed: changedFlag };
|
|
585
587
|
});
|
|
586
588
|
const resolved = resolveCeremonyDial(projectRoot);
|
|
587
589
|
const lines = [
|
|
588
590
|
`\u2713 ${FIELD_CEREMONY_DIAL} updated.`,
|
|
589
|
-
changed
|
|
590
|
-
? " audit: meta/policy-changes.log updated."
|
|
591
|
-
: " no-op: value already matched (audit entry still appended for trail).",
|
|
591
|
+
changed ? " audit: meta/policy-changes.log updated." : POLICY_AUDIT_NOOP_STDOUT,
|
|
592
592
|
formatCeremonyDialStatusLine(resolved),
|
|
593
593
|
];
|
|
594
594
|
return { exitCode: 0, stdout: `${lines.join("\n")}\n`, changed };
|
|
@@ -990,12 +990,6 @@ export function escalateCeremonyDial(projectRoot, options) {
|
|
|
990
990
|
return;
|
|
991
991
|
}
|
|
992
992
|
try {
|
|
993
|
-
const audit = readCeremonyDialAudit(projectRoot);
|
|
994
|
-
const rawSid = audit.raw?.session_id;
|
|
995
|
-
const sid = options.sessionId ??
|
|
996
|
-
(typeof rawSid === "string" && rawSid.length > 0
|
|
997
|
-
? rawSid
|
|
998
|
-
: `dial-${Date.now().toString(36)}`);
|
|
999
993
|
const rank = {
|
|
1000
994
|
minimal: 0,
|
|
1001
995
|
rapid: 1,
|
|
@@ -1012,8 +1006,9 @@ export function escalateCeremonyDial(projectRoot, options) {
|
|
|
1012
1006
|
: baseReason;
|
|
1013
1007
|
const emitter = new RunSummaryEmitter({
|
|
1014
1008
|
projectRoot,
|
|
1015
|
-
sessionId:
|
|
1009
|
+
sessionId: options.sessionId,
|
|
1016
1010
|
env: options.env,
|
|
1011
|
+
component: "ceremony-dial",
|
|
1017
1012
|
});
|
|
1018
1013
|
emitter.emitDialEscalationEvaluation({
|
|
1019
1014
|
tier: outcome === "escalated" ? options.to : from,
|
|
@@ -1065,16 +1060,11 @@ export function escalateCeremonyDial(projectRoot, options) {
|
|
|
1065
1060
|
// #3282: event-driven dial_transition line (fail-open).
|
|
1066
1061
|
if (options.emitRunSummary !== false) {
|
|
1067
1062
|
try {
|
|
1068
|
-
const audit = readCeremonyDialAudit(projectRoot);
|
|
1069
|
-
const rawSid = audit.raw?.session_id;
|
|
1070
|
-
const sid = options.sessionId ??
|
|
1071
|
-
(typeof rawSid === "string" && rawSid.length > 0
|
|
1072
|
-
? rawSid
|
|
1073
|
-
: `dial-${Date.now().toString(36)}`);
|
|
1074
1063
|
const emitter = new RunSummaryEmitter({
|
|
1075
1064
|
projectRoot,
|
|
1076
|
-
sessionId:
|
|
1065
|
+
sessionId: options.sessionId,
|
|
1077
1066
|
env: options.env,
|
|
1067
|
+
component: "ceremony-dial",
|
|
1078
1068
|
});
|
|
1079
1069
|
emitter.emitDialTransition({
|
|
1080
1070
|
from,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Typed plan.policy.deliveryBranch (#3041).
|
|
3
3
|
*
|
|
4
|
-
* Distinct from
|
|
5
|
-
*
|
|
6
|
-
* completion disposition.
|
|
4
|
+
* Distinct from typed `plan.policy.baseBranch` (#3388), the integration-branch
|
|
5
|
+
* source for the shared branch-sync detector. deliveryBranch is dest: where
|
|
6
|
+
* shipped work must land for a delivered completion disposition.
|
|
7
7
|
*/
|
|
8
8
|
import { type GitRunner } from "../session/git.js";
|
|
9
9
|
export declare const FIELD_DELIVERY_BRANCH = "plan.policy.deliveryBranch";
|
|
@@ -16,6 +16,8 @@ export interface DeliveryBranchResult {
|
|
|
16
16
|
readonly source: DeliveryBranchSource;
|
|
17
17
|
readonly error: string | null;
|
|
18
18
|
}
|
|
19
|
+
/** Git-only dest when dest-ref policy has no typed deliveryBranch (#3388). */
|
|
20
|
+
export declare function resolveGitDefaultDeliveryBranch(projectRoot: string, runGit?: GitRunner): string;
|
|
19
21
|
/**
|
|
20
22
|
* Resolve the project's delivery branch (#3041).
|
|
21
23
|
*
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Typed plan.policy.deliveryBranch (#3041).
|
|
3
3
|
*
|
|
4
|
-
* Distinct from
|
|
5
|
-
*
|
|
6
|
-
* completion disposition.
|
|
4
|
+
* Distinct from typed `plan.policy.baseBranch` (#3388), the integration-branch
|
|
5
|
+
* source for the shared branch-sync detector. deliveryBranch is dest: where
|
|
6
|
+
* shipped work must land for a delivered completion disposition.
|
|
7
7
|
*/
|
|
8
8
|
import { defaultGitRunner } from "../session/git.js";
|
|
9
9
|
import { readPlanPolicy } from "./plan-extensions.js";
|
|
@@ -50,6 +50,10 @@ function defaultBranchCandidates(projectRoot, runGit) {
|
|
|
50
50
|
}
|
|
51
51
|
return candidates;
|
|
52
52
|
}
|
|
53
|
+
/** Git-only dest when dest-ref policy has no typed deliveryBranch (#3388). */
|
|
54
|
+
export function resolveGitDefaultDeliveryBranch(projectRoot, runGit = defaultGitRunner) {
|
|
55
|
+
return defaultBranchCandidates(projectRoot, runGit)[0] ?? DEFAULT_DELIVERY_BRANCH_FALLBACK;
|
|
56
|
+
}
|
|
53
57
|
/**
|
|
54
58
|
* Resolve the project's delivery branch (#3041).
|
|
55
59
|
*
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single machine-readable source of truth for per-file size guidance (#3424).
|
|
3
|
+
*
|
|
4
|
+
* `coding.md` and companion prose MUST reference these exports. They are
|
|
5
|
+
* review / planning triggers, not a hard line cap (#1488).
|
|
6
|
+
*/
|
|
7
|
+
/** Preferred size for a focused file. */
|
|
8
|
+
export declare const FILE_SIZE_IDEAL_LINES = 300;
|
|
9
|
+
/** Recommended upper bound before a file should be treated as large. */
|
|
10
|
+
export declare const FILE_SIZE_RECOMMENDED_LINES = 500;
|
|
11
|
+
/**
|
|
12
|
+
* Review-trigger line count. A declared file at or above this size cannot
|
|
13
|
+
* pass preflight without a recorded split plan or cohesion exemption.
|
|
14
|
+
* Size alone is never a fail-closed reject.
|
|
15
|
+
*/
|
|
16
|
+
export declare const FILE_SIZE_REVIEW_TRIGGER_LINES = 1000;
|
|
17
|
+
/** Canonical bundle so callers do not restate the three numbers. */
|
|
18
|
+
export declare const FILE_SIZE_THRESHOLDS: {
|
|
19
|
+
readonly idealLines: 300;
|
|
20
|
+
readonly recommendedLines: 500;
|
|
21
|
+
readonly reviewTriggerLines: 1000;
|
|
22
|
+
};
|
|
23
|
+
export type FileSizeThresholds = typeof FILE_SIZE_THRESHOLDS;
|
|
24
|
+
//# sourceMappingURL=file-size-thresholds.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single machine-readable source of truth for per-file size guidance (#3424).
|
|
3
|
+
*
|
|
4
|
+
* `coding.md` and companion prose MUST reference these exports. They are
|
|
5
|
+
* review / planning triggers, not a hard line cap (#1488).
|
|
6
|
+
*/
|
|
7
|
+
/** Preferred size for a focused file. */
|
|
8
|
+
export const FILE_SIZE_IDEAL_LINES = 300;
|
|
9
|
+
/** Recommended upper bound before a file should be treated as large. */
|
|
10
|
+
export const FILE_SIZE_RECOMMENDED_LINES = 500;
|
|
11
|
+
/**
|
|
12
|
+
* Review-trigger line count. A declared file at or above this size cannot
|
|
13
|
+
* pass preflight without a recorded split plan or cohesion exemption.
|
|
14
|
+
* Size alone is never a fail-closed reject.
|
|
15
|
+
*/
|
|
16
|
+
export const FILE_SIZE_REVIEW_TRIGGER_LINES = 1000;
|
|
17
|
+
/** Canonical bundle so callers do not restate the three numbers. */
|
|
18
|
+
export const FILE_SIZE_THRESHOLDS = {
|
|
19
|
+
idealLines: FILE_SIZE_IDEAL_LINES,
|
|
20
|
+
recommendedLines: FILE_SIZE_RECOMMENDED_LINES,
|
|
21
|
+
reviewTriggerLines: FILE_SIZE_REVIEW_TRIGGER_LINES,
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=file-size-thresholds.js.map
|