@deftai/directive-core 0.96.0 → 0.97.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/cache/archive.js +10 -4
- package/dist/check/gate-lists.js +8 -0
- package/dist/consumer-check-contract/evaluate.d.ts +124 -0
- package/dist/consumer-check-contract/evaluate.js +699 -0
- package/dist/consumer-check-contract/index.d.ts +5 -0
- package/dist/consumer-check-contract/index.js +5 -0
- package/dist/delivery-attempt/disk-begin.d.ts +51 -0
- package/dist/delivery-attempt/disk-begin.js +68 -0
- package/dist/delivery-attempt/evaluate.d.ts +26 -0
- package/dist/delivery-attempt/evaluate.js +443 -0
- package/dist/delivery-attempt/fingerprint.d.ts +32 -0
- package/dist/delivery-attempt/fingerprint.js +100 -0
- package/dist/delivery-attempt/handoff.d.ts +25 -0
- package/dist/delivery-attempt/handoff.js +102 -0
- package/dist/delivery-attempt/index.d.ts +17 -0
- package/dist/delivery-attempt/index.js +17 -0
- package/dist/delivery-attempt/ledger.d.ts +169 -0
- package/dist/delivery-attempt/ledger.js +758 -0
- package/dist/delivery-attempt/material-delta.d.ts +38 -0
- package/dist/delivery-attempt/material-delta.js +126 -0
- package/dist/delivery-attempt/types.d.ts +210 -0
- package/dist/delivery-attempt/types.js +77 -0
- package/dist/doctor/index.d.ts +1 -0
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/main.js +12 -0
- package/dist/doctor/openclaw-soft-rebind.d.ts +26 -0
- package/dist/doctor/openclaw-soft-rebind.js +164 -0
- package/dist/hooks/dispatcher.d.ts +2 -1
- package/dist/hooks/dispatcher.js +63 -9
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/init-deposit/gitignore.js +7 -0
- package/dist/init-deposit/init-deposit.js +5 -0
- package/dist/init-deposit/refresh.js +3 -0
- package/dist/pr-merge-readiness/ci-gate.d.ts +29 -1
- package/dist/pr-merge-readiness/ci-gate.js +191 -24
- package/dist/pr-merge-readiness/compute.js +10 -1
- package/dist/pr-merge-readiness/index.d.ts +2 -1
- package/dist/pr-merge-readiness/index.js +2 -1
- package/dist/pr-merge-readiness/output.js +14 -0
- package/dist/pr-merge-readiness/platform-status.d.ts +29 -0
- package/dist/pr-merge-readiness/platform-status.js +49 -0
- package/dist/pr-watch/constants.d.ts +10 -0
- package/dist/pr-watch/constants.js +12 -1
- package/dist/pr-watch/main.js +16 -1
- package/dist/pr-watch/probe.js +13 -1
- package/dist/pr-watch/types.d.ts +3 -2
- package/dist/pr-watch/watch.js +14 -7
- package/dist/scope-provenance/digest.d.ts +67 -0
- package/dist/scope-provenance/digest.js +188 -0
- package/dist/scope-provenance/evaluate.d.ts +82 -0
- package/dist/scope-provenance/evaluate.js +528 -0
- package/dist/scope-provenance/index.d.ts +6 -0
- package/dist/scope-provenance/index.js +6 -0
- package/dist/session/compact-ritual.d.ts +96 -0
- package/dist/session/compact-ritual.js +237 -0
- package/dist/session/compact-ritual.spec.d.ts +2 -0
- package/dist/session/compact-ritual.spec.js +21 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/openclaw-soft-rebind-deposit.d.ts +46 -0
- package/dist/session/openclaw-soft-rebind-deposit.js +165 -0
- package/dist/test-boundary/evaluate.d.ts +54 -0
- package/dist/test-boundary/evaluate.js +368 -0
- package/dist/test-boundary/index.d.ts +6 -0
- package/dist/test-boundary/index.js +6 -0
- package/dist/test-boundary/policy.d.ts +52 -0
- package/dist/test-boundary/policy.js +182 -0
- package/dist/triage/bootstrap/gitignore.d.ts +1 -1
- package/dist/triage/bootstrap/gitignore.js +15 -1
- package/dist/vbrief-activate/activate.js +22 -6
- package/dist/xbrief/styles.js +33 -17
- package/package.json +7 -3
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor check + --fix wire for OpenClaw soft AGENTS re-bind skill (#3171).
|
|
3
|
+
*
|
|
4
|
+
* Complements always-pins (#3001/#3008) and L2 product commands (#3064). This
|
|
5
|
+
* skill is the required durable soft post-amnesia surface for OpenClaw — not
|
|
6
|
+
* claimed via file-host PreCompact hooks alone.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { formatOpenClawSoftRebindSkillMarkdown, isManagedOpenClawSoftRebindSkill, OPENCLAW_SOFT_REBIND_SKILL_ID, } from "../session/compact-ritual.js";
|
|
12
|
+
import { assessOpenClawSoftRebindSkill, depositOpenClawSoftRebindSkill, } from "../session/openclaw-soft-rebind-deposit.js";
|
|
13
|
+
import { detectOpenClaw, listInScopeSkillsDirs } from "./openclaw-skills.js";
|
|
14
|
+
/** Stable doctor check id for JSON findings. */
|
|
15
|
+
export const OPENCLAW_SOFT_REBIND_CHECK = "openclaw-soft-agents-rebind";
|
|
16
|
+
const DOC_OPENCLAW_HOST = "docs/openclaw-agent-host.md";
|
|
17
|
+
const REMEDIATION_FIX = "deft doctor --fix";
|
|
18
|
+
function defaultIsDir(path) {
|
|
19
|
+
try {
|
|
20
|
+
return statSync(path).isDirectory();
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function assessGaps(skillsDirs) {
|
|
27
|
+
const expected = formatOpenClawSoftRebindSkillMarkdown();
|
|
28
|
+
const missing = [];
|
|
29
|
+
const stale = [];
|
|
30
|
+
let present = 0;
|
|
31
|
+
for (const skillsDir of skillsDirs) {
|
|
32
|
+
const path = join(skillsDir, OPENCLAW_SOFT_REBIND_SKILL_ID, "SKILL.md");
|
|
33
|
+
if (!existsSync(path)) {
|
|
34
|
+
missing.push(`${skillsDir}/${OPENCLAW_SOFT_REBIND_SKILL_ID}`);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
let raw;
|
|
38
|
+
try {
|
|
39
|
+
raw = readFileSync(path, "utf8");
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
missing.push(`${skillsDir}/${OPENCLAW_SOFT_REBIND_SKILL_ID}`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Unmanaged content at the required slug is incomplete health, not pass
|
|
46
|
+
// (Greptile P1 #3171). Doctor --fix overwrites via deposit.
|
|
47
|
+
if (!isManagedOpenClawSoftRebindSkill(raw) || raw !== expected) {
|
|
48
|
+
stale.push(`${skillsDir}/${OPENCLAW_SOFT_REBIND_SKILL_ID}`);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
present += 1;
|
|
52
|
+
}
|
|
53
|
+
return { missing, stale, present };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Doctor check: OpenClaw soft AGENTS re-bind skill present and current.
|
|
57
|
+
* No-ops when OpenClaw is not detected. Fix mode deposits managed skill.
|
|
58
|
+
*/
|
|
59
|
+
export function runOpenClawSoftRebindCheck(sink, addFinding, options) {
|
|
60
|
+
const seams = options.seams ?? {};
|
|
61
|
+
const env = seams.openclawEnv ?? process.env;
|
|
62
|
+
const homeDirFn = seams.openclawHomeDir ?? (() => homedir());
|
|
63
|
+
const isDir = seams.isDir ?? defaultIsDir;
|
|
64
|
+
const detect = detectOpenClaw(env, { homeDir: homeDirFn(), isDir });
|
|
65
|
+
if (!detect.detected) {
|
|
66
|
+
sink.info(`${OPENCLAW_SOFT_REBIND_CHECK}: skip -- OpenClaw not detected`);
|
|
67
|
+
addFinding({
|
|
68
|
+
severity: "skip",
|
|
69
|
+
message: "OpenClaw not detected",
|
|
70
|
+
check: OPENCLAW_SOFT_REBIND_CHECK,
|
|
71
|
+
status: "skip",
|
|
72
|
+
reason: "openclaw-not-detected",
|
|
73
|
+
});
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const skillsDirs = listInScopeSkillsDirs(detect.stateDir, options.allAgents, {
|
|
77
|
+
isDir,
|
|
78
|
+
});
|
|
79
|
+
const gaps = assessGaps(skillsDirs);
|
|
80
|
+
if (gaps.missing.length === 0 && gaps.stale.length === 0) {
|
|
81
|
+
const scope = options.allAgents ? "main + workspace-* seats" : "main workspace";
|
|
82
|
+
const message = `${OPENCLAW_SOFT_REBIND_CHECK}: soft AGENTS re-bind skill present ` +
|
|
83
|
+
`(${OPENCLAW_SOFT_REBIND_SKILL_ID}) in ${scope}`;
|
|
84
|
+
sink.success(message);
|
|
85
|
+
addFinding({
|
|
86
|
+
severity: "skip",
|
|
87
|
+
message,
|
|
88
|
+
check: OPENCLAW_SOFT_REBIND_CHECK,
|
|
89
|
+
status: "present",
|
|
90
|
+
skill: OPENCLAW_SOFT_REBIND_SKILL_ID,
|
|
91
|
+
skills_dirs: skillsDirs,
|
|
92
|
+
});
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (options.fixMode) {
|
|
96
|
+
const depositResult = depositOpenClawSoftRebindSkill({
|
|
97
|
+
env,
|
|
98
|
+
homeDir: homeDirFn(),
|
|
99
|
+
allAgents: options.allAgents,
|
|
100
|
+
isDir,
|
|
101
|
+
skillsDirs,
|
|
102
|
+
});
|
|
103
|
+
const after = assessGaps(skillsDirs);
|
|
104
|
+
if (after.missing.length === 0 && after.stale.length === 0) {
|
|
105
|
+
const message = `${OPENCLAW_SOFT_REBIND_CHECK}: deposited soft AGENTS re-bind skill; ` +
|
|
106
|
+
`restart OpenClaw gateway or start a new session (${DOC_OPENCLAW_HOST})`;
|
|
107
|
+
sink.success(message);
|
|
108
|
+
addFinding({
|
|
109
|
+
severity: "skip",
|
|
110
|
+
message,
|
|
111
|
+
check: OPENCLAW_SOFT_REBIND_CHECK,
|
|
112
|
+
status: "fixed",
|
|
113
|
+
written: depositResult.writtenPaths,
|
|
114
|
+
});
|
|
115
|
+
return depositResult;
|
|
116
|
+
}
|
|
117
|
+
// Partial fix: report remaining gaps from post-deposit assessment (SLizard P2).
|
|
118
|
+
const partsAfter = [];
|
|
119
|
+
if (after.missing.length > 0) {
|
|
120
|
+
partsAfter.push(`missing=${after.missing.join(", ")}`);
|
|
121
|
+
}
|
|
122
|
+
if (after.stale.length > 0) {
|
|
123
|
+
partsAfter.push(`stale=${after.stale.join(", ")}`);
|
|
124
|
+
}
|
|
125
|
+
const messageAfter = `${OPENCLAW_SOFT_REBIND_CHECK}: OpenClaw soft AGENTS re-bind skill incomplete after fix ` +
|
|
126
|
+
`(${partsAfter.join("; ")}). Remediation: ${REMEDIATION_FIX} — see ${DOC_OPENCLAW_HOST}`;
|
|
127
|
+
sink.warn(messageAfter);
|
|
128
|
+
addFinding({
|
|
129
|
+
severity: "warning",
|
|
130
|
+
message: messageAfter,
|
|
131
|
+
check: OPENCLAW_SOFT_REBIND_CHECK,
|
|
132
|
+
status: "incomplete",
|
|
133
|
+
missing: after.missing,
|
|
134
|
+
stale: after.stale,
|
|
135
|
+
written: depositResult.writtenPaths,
|
|
136
|
+
suggestion: REMEDIATION_FIX,
|
|
137
|
+
docs: [DOC_OPENCLAW_HOST],
|
|
138
|
+
});
|
|
139
|
+
return depositResult;
|
|
140
|
+
}
|
|
141
|
+
const parts = [];
|
|
142
|
+
if (gaps.missing.length > 0) {
|
|
143
|
+
parts.push(`missing=${gaps.missing.join(", ")}`);
|
|
144
|
+
}
|
|
145
|
+
if (gaps.stale.length > 0) {
|
|
146
|
+
parts.push(`stale=${gaps.stale.join(", ")}`);
|
|
147
|
+
}
|
|
148
|
+
const message = `${OPENCLAW_SOFT_REBIND_CHECK}: OpenClaw soft AGENTS re-bind skill incomplete ` +
|
|
149
|
+
`(${parts.join("; ")}). Remediation: ${REMEDIATION_FIX} — see ${DOC_OPENCLAW_HOST}`;
|
|
150
|
+
sink.warn(message);
|
|
151
|
+
addFinding({
|
|
152
|
+
severity: "warning",
|
|
153
|
+
message,
|
|
154
|
+
check: OPENCLAW_SOFT_REBIND_CHECK,
|
|
155
|
+
status: "incomplete",
|
|
156
|
+
missing: gaps.missing,
|
|
157
|
+
stale: gaps.stale,
|
|
158
|
+
suggestion: REMEDIATION_FIX,
|
|
159
|
+
docs: [DOC_OPENCLAW_HOST],
|
|
160
|
+
});
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
export { assessOpenClawSoftRebindSkill, depositOpenClawSoftRebindSkill };
|
|
164
|
+
//# sourceMappingURL=openclaw-soft-rebind.js.map
|
|
@@ -140,7 +140,8 @@ export declare function decideHook(input: HookDispatchInput, seams?: HookPolicyS
|
|
|
140
140
|
* Cursor deposits use `failClosed: true`. Cursor treats empty/null stdout as a
|
|
141
141
|
* hook failure and blocks the tool — so Cursor allows must emit explicit
|
|
142
142
|
* `{"permission":"allow"}`. Other hosts keep empty allow so the host permission
|
|
143
|
-
* flow is unchanged.
|
|
143
|
+
* flow is unchanged — except session.start / session.compact soft re-bind
|
|
144
|
+
* injection (#3171), which surfaces checklist text without a write tool.
|
|
144
145
|
*
|
|
145
146
|
* Cursor stdout always includes `code` (stable machine-readable decision code)
|
|
146
147
|
* so agents can distinguish policy denials from host-integration failures
|
package/dist/hooks/dispatcher.js
CHANGED
|
@@ -7,6 +7,7 @@ import { evaluateIntentCeilingFromEnv } from "../policy/intent-ceiling.js";
|
|
|
7
7
|
import { detectNoDeftDirective, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, } from "../policy/no-deft-directive.js";
|
|
8
8
|
import { classifyMcpTool, DEFAULT_RUNTIME_AUTHORITY_POLICY, evaluateRuntimeAuthorityDirectWrite, evaluateRuntimeAuthorityShellOp, listShellOps, loadRuntimeAuthorityFromProject, } from "../policy/runtime-authority.js";
|
|
9
9
|
import { loadStoryWriteFenceFromPath, resolveWriteFence } from "../policy/write-fence.js";
|
|
10
|
+
import { appendSoftAgentsRebindToMessage, decisionCarriesSoftAgentsRebind, formatSoftAgentsRebindChecklist, } from "../session/compact-ritual.js";
|
|
10
11
|
import { detectBranch } from "../session/git.js";
|
|
11
12
|
import { emitSessionRitualBlockedProcessCost } from "../session/process-cost.js";
|
|
12
13
|
import { markRitualStaleAfterCompact } from "../session/ritual-sentinel.js";
|
|
@@ -716,7 +717,8 @@ export function decideHook(input, seams = {}) {
|
|
|
716
717
|
host: input.host,
|
|
717
718
|
toolName: null,
|
|
718
719
|
projectRoot,
|
|
719
|
-
|
|
720
|
+
// Soft checklist still surfaces after compact even when ritual was absent (#3171).
|
|
721
|
+
message: appendSoftAgentsRebindToMessage(result.message),
|
|
720
722
|
scopePath: null,
|
|
721
723
|
};
|
|
722
724
|
}
|
|
@@ -727,7 +729,7 @@ export function decideHook(input, seams = {}) {
|
|
|
727
729
|
host: input.host,
|
|
728
730
|
toolName: null,
|
|
729
731
|
projectRoot,
|
|
730
|
-
message: result.message,
|
|
732
|
+
message: appendSoftAgentsRebindToMessage(result.message),
|
|
731
733
|
scopePath: null,
|
|
732
734
|
};
|
|
733
735
|
}
|
|
@@ -739,8 +741,8 @@ export function decideHook(input, seams = {}) {
|
|
|
739
741
|
host: input.host,
|
|
740
742
|
toolName: null,
|
|
741
743
|
projectRoot,
|
|
742
|
-
message: "Directive compact re-arm bookkeeping failed on its non-blocking path: " +
|
|
743
|
-
`${String(cause)}
|
|
744
|
+
message: appendSoftAgentsRebindToMessage("Directive compact re-arm bookkeeping failed on its non-blocking path: " +
|
|
745
|
+
`${String(cause)}`),
|
|
744
746
|
scopePath: null,
|
|
745
747
|
};
|
|
746
748
|
}
|
|
@@ -775,8 +777,9 @@ export function decideHook(input, seams = {}) {
|
|
|
775
777
|
host: input.host,
|
|
776
778
|
toolName: null,
|
|
777
779
|
projectRoot,
|
|
778
|
-
|
|
779
|
-
|
|
780
|
+
// Best-effort soft cue on SessionStart (Codex gap + resume/amnesia) (#3171).
|
|
781
|
+
message: appendSoftAgentsRebindToMessage(`Directive SessionStart bookkeeping reported exit ${result.code} on its non-blocking path` +
|
|
782
|
+
`${detail.length > 0 ? `: ${detail}` : "."}`),
|
|
780
783
|
scopePath: null,
|
|
781
784
|
};
|
|
782
785
|
}
|
|
@@ -789,7 +792,7 @@ export function decideHook(input, seams = {}) {
|
|
|
789
792
|
host: input.host,
|
|
790
793
|
toolName: null,
|
|
791
794
|
projectRoot,
|
|
792
|
-
message: `Directive SessionStart bookkeeping failed on its non-blocking path: ${String(cause)}
|
|
795
|
+
message: appendSoftAgentsRebindToMessage(`Directive SessionStart bookkeeping failed on its non-blocking path: ${String(cause)}`),
|
|
793
796
|
scopePath: null,
|
|
794
797
|
};
|
|
795
798
|
}
|
|
@@ -800,7 +803,8 @@ export function decideHook(input, seams = {}) {
|
|
|
800
803
|
host: input.host,
|
|
801
804
|
toolName: null,
|
|
802
805
|
projectRoot,
|
|
803
|
-
|
|
806
|
+
// Soft AGENTS re-bind on SessionStart without requiring a write tool (#3171 / #2769).
|
|
807
|
+
message: appendSoftAgentsRebindToMessage("SessionStart bookkeeping completed on a non-blocking path."),
|
|
804
808
|
scopePath: null,
|
|
805
809
|
};
|
|
806
810
|
}
|
|
@@ -881,13 +885,27 @@ export function decideHook(input, seams = {}) {
|
|
|
881
885
|
}
|
|
882
886
|
return inspectMutationGates(input, toolName, seams, { proposedLifecycleExempt: true });
|
|
883
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* Soft AGENTS re-bind text for host injection when decision carries soft path (#3171).
|
|
890
|
+
* Prefer the checklist portion of the decision message; fall back to SoT formatter.
|
|
891
|
+
*/
|
|
892
|
+
function softAgentsRebindWireText(decision) {
|
|
893
|
+
if (!decisionCarriesSoftAgentsRebind({ event: decision.event, code: decision.code })) {
|
|
894
|
+
return null;
|
|
895
|
+
}
|
|
896
|
+
if (decision.message.includes("Soft AGENTS re-bind checklist:")) {
|
|
897
|
+
return decision.message;
|
|
898
|
+
}
|
|
899
|
+
return formatSoftAgentsRebindChecklist();
|
|
900
|
+
}
|
|
884
901
|
/**
|
|
885
902
|
* Render host-facing hook output.
|
|
886
903
|
*
|
|
887
904
|
* Cursor deposits use `failClosed: true`. Cursor treats empty/null stdout as a
|
|
888
905
|
* hook failure and blocks the tool — so Cursor allows must emit explicit
|
|
889
906
|
* `{"permission":"allow"}`. Other hosts keep empty allow so the host permission
|
|
890
|
-
* flow is unchanged.
|
|
907
|
+
* flow is unchanged — except session.start / session.compact soft re-bind
|
|
908
|
+
* injection (#3171), which surfaces checklist text without a write tool.
|
|
891
909
|
*
|
|
892
910
|
* Cursor stdout always includes `code` (stable machine-readable decision code)
|
|
893
911
|
* so agents can distinguish policy denials from host-integration failures
|
|
@@ -896,9 +914,45 @@ export function decideHook(input, seams = {}) {
|
|
|
896
914
|
*/
|
|
897
915
|
export function renderHostDecision(host, decision) {
|
|
898
916
|
if (decision.verdict === "allow") {
|
|
917
|
+
const soft = softAgentsRebindWireText(decision);
|
|
899
918
|
if (host === "cursor") {
|
|
919
|
+
if (decision.event === "session.start" && soft !== null) {
|
|
920
|
+
// Cursor sessionStart injects additional_context into the conversation.
|
|
921
|
+
return JSON.stringify({
|
|
922
|
+
permission: "allow",
|
|
923
|
+
code: decision.code,
|
|
924
|
+
additional_context: soft,
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
if (decision.event === "session.compact" && soft !== null) {
|
|
928
|
+
// Cursor preCompact is observational; user_message surfaces the soft cue.
|
|
929
|
+
// Hard re-arm still ran via bookkeeping; agent path also gets SessionStart on resume.
|
|
930
|
+
return JSON.stringify({
|
|
931
|
+
user_message: soft,
|
|
932
|
+
code: decision.code,
|
|
933
|
+
});
|
|
934
|
+
}
|
|
900
935
|
return JSON.stringify({ permission: "allow", code: decision.code });
|
|
901
936
|
}
|
|
937
|
+
if (soft !== null &&
|
|
938
|
+
(decision.event === "session.start" || decision.event === "session.compact")) {
|
|
939
|
+
if (host === "claude" || host === "codex") {
|
|
940
|
+
const hookEventName = decision.event === "session.start" ? "SessionStart" : "PostCompact";
|
|
941
|
+
return JSON.stringify({
|
|
942
|
+
hookSpecificOutput: {
|
|
943
|
+
hookEventName,
|
|
944
|
+
additionalContext: soft,
|
|
945
|
+
},
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
if (host === "grok") {
|
|
949
|
+
return JSON.stringify({
|
|
950
|
+
decision: "allow",
|
|
951
|
+
reason: soft,
|
|
952
|
+
additional_context: soft,
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
}
|
|
902
956
|
return "";
|
|
903
957
|
}
|
|
904
958
|
switch (host) {
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,9 @@ export * as branch from "./branch/index.js";
|
|
|
14
14
|
export * as cache from "./cache/index.js";
|
|
15
15
|
export * as capacity from "./capacity/index.js";
|
|
16
16
|
export * as codebase from "./codebase/index.js";
|
|
17
|
+
export * as consumerCheckContract from "./consumer-check-contract/index.js";
|
|
17
18
|
export * from "./coverage-hotspots/index.js";
|
|
19
|
+
export * as deliveryAttempt from "./delivery-attempt/index.js";
|
|
18
20
|
export * as doctor from "./doctor/index.js";
|
|
19
21
|
export * from "./encoding/index.js";
|
|
20
22
|
export * as escalation from "./escalation/index.js";
|
|
@@ -52,11 +54,13 @@ export * as render from "./render/index.js";
|
|
|
52
54
|
export * as resolution from "./resolution/index.js";
|
|
53
55
|
export * as scm from "./scm/index.js";
|
|
54
56
|
export * as scope from "./scope/index.js";
|
|
57
|
+
export * as scopeProvenance from "./scope-provenance/index.js";
|
|
55
58
|
export * as session from "./session/index.js";
|
|
56
59
|
export * as slash from "./slash/index.js";
|
|
57
60
|
export * as slice from "./slice/index.js";
|
|
58
61
|
export * as storyReady from "./story-ready/index.js";
|
|
59
62
|
export * as swarm from "./swarm/index.js";
|
|
63
|
+
export * as testBoundary from "./test-boundary/index.js";
|
|
60
64
|
export * as toolEvents from "./tool-events/index.js";
|
|
61
65
|
export * as triage from "./triage/index.js";
|
|
62
66
|
export * as userConfig from "./user-config/index.js";
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,9 @@ export * as branch from "./branch/index.js";
|
|
|
14
14
|
export * as cache from "./cache/index.js";
|
|
15
15
|
export * as capacity from "./capacity/index.js";
|
|
16
16
|
export * as codebase from "./codebase/index.js";
|
|
17
|
+
export * as consumerCheckContract from "./consumer-check-contract/index.js";
|
|
17
18
|
export * from "./coverage-hotspots/index.js";
|
|
19
|
+
export * as deliveryAttempt from "./delivery-attempt/index.js";
|
|
18
20
|
export * as doctor from "./doctor/index.js";
|
|
19
21
|
export * from "./encoding/index.js";
|
|
20
22
|
export * as escalation from "./escalation/index.js";
|
|
@@ -53,11 +55,13 @@ export * as render from "./render/index.js";
|
|
|
53
55
|
export * as resolution from "./resolution/index.js";
|
|
54
56
|
export * as scm from "./scm/index.js";
|
|
55
57
|
export * as scope from "./scope/index.js";
|
|
58
|
+
export * as scopeProvenance from "./scope-provenance/index.js";
|
|
56
59
|
export * as session from "./session/index.js";
|
|
57
60
|
export * as slash from "./slash/index.js";
|
|
58
61
|
export * as slice from "./slice/index.js";
|
|
59
62
|
export * as storyReady from "./story-ready/index.js";
|
|
60
63
|
export * as swarm from "./swarm/index.js";
|
|
64
|
+
export * as testBoundary from "./test-boundary/index.js";
|
|
61
65
|
export * as toolEvents from "./tool-events/index.js";
|
|
62
66
|
export * as triage from "./triage/index.js";
|
|
63
67
|
export * as userConfig from "./user-config/index.js";
|
|
@@ -37,6 +37,11 @@ export const CANONICAL_GITIGNORE_BASELINE = [
|
|
|
37
37
|
"vbrief/.triage-cache/scope-lifecycle.jsonl",
|
|
38
38
|
"vbrief/.triage-cache/decompositions/",
|
|
39
39
|
"vbrief/.triage-cache/doctor-state.json",
|
|
40
|
+
// Per-clone session state (#3146): throttle / release-availability JSON
|
|
41
|
+
// written under the lifecycle .triage-cache; selective ignore only (hybrid
|
|
42
|
+
// #1144 — never blanket-ignore the whole .triage-cache directory).
|
|
43
|
+
"vbrief/.triage-cache/staleness-tickler-state.json",
|
|
44
|
+
"vbrief/.triage-cache/release-availability-state.json",
|
|
40
45
|
// Symmetric `xbrief/` layout entries (#2348). On the migrated `xbrief/` tree
|
|
41
46
|
// the engine writes operator-private triage-cache files to
|
|
42
47
|
// `xbrief/.triage-cache/`; without these the paths are trackable, violating
|
|
@@ -47,6 +52,8 @@ export const CANONICAL_GITIGNORE_BASELINE = [
|
|
|
47
52
|
"xbrief/.triage-cache/scope-lifecycle.jsonl",
|
|
48
53
|
"xbrief/.triage-cache/decompositions/",
|
|
49
54
|
"xbrief/.triage-cache/doctor-state.json",
|
|
55
|
+
"xbrief/.triage-cache/staleness-tickler-state.json",
|
|
56
|
+
"xbrief/.triage-cache/release-availability-state.json",
|
|
50
57
|
"vbrief/*.lock",
|
|
51
58
|
".deft/core.bak-*/",
|
|
52
59
|
".deft/*.bak-*",
|
|
@@ -15,6 +15,7 @@ import { resolveInstalledContentRoot } from "../deposit/resolve-content.js";
|
|
|
15
15
|
import { readCorePackageVersion } from "../engine-version.js";
|
|
16
16
|
import { stampLiveGeneration } from "../freshness/generation.js";
|
|
17
17
|
import { renderProjectDefinition } from "../render/project-render.js";
|
|
18
|
+
import { depositOpenClawSoftRebindSkill } from "../session/openclaw-soft-rebind-deposit.js";
|
|
18
19
|
import { depositOpenClawL2ProductCommands } from "../slash/openclaw-deposit.js";
|
|
19
20
|
import { agentHookReadinessJson, evaluateAgentHookReadiness, evaluateAgentHookReadinessSafely, } from "../verify-env/agent-hook-readiness.js";
|
|
20
21
|
import { removeStaleMigratedFrameworkNarrative } from "../xbrief-migrate/migrate-project.js";
|
|
@@ -201,6 +202,10 @@ export async function runInitDeposit(args, io, seams = {}) {
|
|
|
201
202
|
writeConsumerGitHooks(projectDir, deftDir, io, seams.gitHooks);
|
|
202
203
|
writeAgentHookDeposit(projectDir, io);
|
|
203
204
|
writeSlashCommandDeposit(projectDir, io);
|
|
205
|
+
// #3171: OpenClaw soft AGENTS re-bind skill when OC signals present (fail-closed otherwise).
|
|
206
|
+
depositOpenClawSoftRebindSkill({
|
|
207
|
+
/* env defaults; skip when OpenClaw not detected */
|
|
208
|
+
});
|
|
204
209
|
// #3064: OpenClaw L2 product-command skills when OC signals present (fail-closed otherwise).
|
|
205
210
|
depositOpenClawL2ProductCommands({
|
|
206
211
|
projectRoot: projectDir,
|
|
@@ -22,6 +22,7 @@ import { resolveLifecycleRoot } from "../layout/resolve.js";
|
|
|
22
22
|
import { detectNoDeftDirective, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, NO_DEFT_DIRECTIVE_INCONSISTENT_POLICY, } from "../policy/no-deft-directive.js";
|
|
23
23
|
import { runOrgForceOnMigration } from "../policy/org-force-on-migration.js";
|
|
24
24
|
import { checkLocalEngineIntegrity, classify, ENGINE_PACKAGE, plan, renderGlobalInstall, resolveEngine, } from "../resolution/index.js";
|
|
25
|
+
import { depositOpenClawSoftRebindSkill } from "../session/openclaw-soft-rebind-deposit.js";
|
|
25
26
|
import { depositOpenClawL2ProductCommands } from "../slash/openclaw-deposit.js";
|
|
26
27
|
import { gitPorcelain } from "../story-ready/git.js";
|
|
27
28
|
import { agentHookReadinessJson, evaluateAgentHookReadiness, evaluateAgentHookReadinessSafely, } from "../verify-env/agent-hook-readiness.js";
|
|
@@ -506,6 +507,8 @@ export async function runRefreshDeposit(args, io, seams = {}) {
|
|
|
506
507
|
// #75 residual: multi-host thin skill discovery (mirror `.agents/skills` inventory).
|
|
507
508
|
writeMultiHostSkillDiscovery(projectDir, io);
|
|
508
509
|
writeSlashCommandDeposit(projectDir, io);
|
|
510
|
+
// #3171: OpenClaw soft AGENTS re-bind skill when OC signals present (fail-closed otherwise).
|
|
511
|
+
depositOpenClawSoftRebindSkill({});
|
|
509
512
|
// #3064: OpenClaw L2 product-command skills when OC signals present (fail-closed otherwise).
|
|
510
513
|
depositOpenClawL2ProductCommands({
|
|
511
514
|
projectRoot: projectDir,
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import type { CheckRunRecord } from "./gh.js";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Bot-reviewer check-runs are not CI workflow jobs. Presence of only these
|
|
4
|
+
* (or empty check-runs) is the `ci_never_scheduled` weather signal (#3167).
|
|
5
|
+
*/
|
|
6
|
+
export declare function isBotReviewCheck(name: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Suite family for cancelled↔green sibling matching (#3167 / Greptile P1).
|
|
9
|
+
* Unrelated greens (CodeQL, Socket, …) must not clear a cancelled TypeScript/Go lane.
|
|
10
|
+
* Returns null when the check is not a TS/Go CI suite job.
|
|
11
|
+
*/
|
|
12
|
+
export declare function suiteFamilyOf(name: string): "typescript" | "go" | null;
|
|
13
|
+
/**
|
|
14
|
+
* Branch-protection SoT aggregators only (#3168 map). Primary/failover lanes are
|
|
15
|
+
* not authoritative: a green primary must not clear a cancelled aggregator.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isAuthoritativeSuiteAggregator(name: string): boolean;
|
|
18
|
+
export type CiReadyState = "ready" | "blocked" | "ci_failures" | "not_ready_yet" | "runner_capacity_stall" | "ci_never_scheduled" | "ci_cancelled_no_failover" | "skipped";
|
|
3
19
|
export interface CiGateOptions {
|
|
4
20
|
readonly skipCi?: boolean;
|
|
5
21
|
readonly ignoreCheckNames?: readonly string[];
|
|
@@ -23,6 +39,8 @@ export interface CiGateSummary {
|
|
|
23
39
|
readonly pending_required: readonly string[];
|
|
24
40
|
/** Required checks classified as capacity-stalled (#2672). */
|
|
25
41
|
readonly capacity_stalled_required: readonly string[];
|
|
42
|
+
/** Required checks cancelled without a green failover sibling (#3167). */
|
|
43
|
+
readonly cancelled_required: readonly string[];
|
|
26
44
|
readonly conclusions: readonly CiCheckConclusion[];
|
|
27
45
|
}
|
|
28
46
|
export interface CiGateResult {
|
|
@@ -30,5 +48,15 @@ export interface CiGateResult {
|
|
|
30
48
|
readonly summary: CiGateSummary;
|
|
31
49
|
}
|
|
32
50
|
export declare function buildCiSummaryLine(summary: CiGateSummary): string;
|
|
51
|
+
/**
|
|
52
|
+
* Classify required CI weather for a HEAD check-run list (#2169 / #2672 / #3167).
|
|
53
|
+
*
|
|
54
|
+
* Distinct ready_state codes:
|
|
55
|
+
* - `ci_never_scheduled` — no CI workflow check-runs (bots alone / empty)
|
|
56
|
+
* - `runner_capacity_stall` — queued past budget, no runner claimed
|
|
57
|
+
* - `ci_failures` — completed failure / timed_out with product evidence
|
|
58
|
+
* - `ci_cancelled_no_failover` — only cancelled failures; no green failover
|
|
59
|
+
* - `not_ready_yet` / `ready` / `blocked` / `skipped` — legacy + residual
|
|
60
|
+
*/
|
|
33
61
|
export declare function evaluateCiGate(checkRuns: readonly CheckRunRecord[], options?: CiGateOptions): CiGateResult;
|
|
34
62
|
//# sourceMappingURL=ci-gate.d.ts.map
|