@event4u/agent-config 14.5.0 → 14.6.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +128 -0
- package/dist/agent-src/commands/analyze/decision.md +7 -0
- package/dist/agent-src/commands/optimize/project.md +10 -0
- package/dist/agent-src/commands/roadmap/process-full.md +45 -3
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +130 -1
- package/dist/agent-src/rules/decision-revisit-gate.md +108 -7
- package/dist/agent-src/skills/adr-create/SKILL.md +25 -3
- package/dist/agent-src/skills/decision-review/SKILL.md +18 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli-delegate/{chunk-ZPSXJTLI.js → chunk-P6LQDIWK.js} +15 -1
- package/dist/cli-delegate/cmd_conformance.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +8 -8
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +334 -77
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/router.json +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +49 -0
- package/package.json +1 -1
- package/src/config/estate-count-budget.json +29 -1
- package/src/config/pack-size-budget.json +3 -2
- package/src/scripts/_lib/layer_overlap_notice.ts +85 -0
- package/src/scripts/_lib/scope_guard.sh +62 -3
- package/src/scripts/_lib/subagent_capsule.ts +81 -1
- package/src/scripts/adr/regenerate_index.ts +13 -2
- package/src/scripts/adr_cite_check.ts +424 -0
- package/src/scripts/check_adr_frontmatter.ts +187 -1
- package/src/scripts/check_single_delivery.ts +473 -0
- package/src/scripts/hooks/run_continuation_hook.ts +884 -68
- package/src/scripts/install.sh +12 -2
- package/src/scripts/memory_consolidation.ts +189 -0
- package/src/scripts/memory_eviction.ts +384 -0
- package/src/scripts/report_layer_overlap.ts +72 -0
- package/src/scripts/report_memory_pointers.ts +622 -0
- package/src/scripts/session_register_hook.ts +104 -15
package/dist/hooks/dispatch.js
CHANGED
|
@@ -11921,9 +11921,9 @@ function user_global_settings_paths() {
|
|
|
11921
11921
|
if (flat !== null) {
|
|
11922
11922
|
paths.push(flat);
|
|
11923
11923
|
}
|
|
11924
|
-
const
|
|
11925
|
-
if (
|
|
11926
|
-
paths.push(
|
|
11924
|
+
const canonical2 = resolve_with_fallback(USER_GLOBAL_CANONICAL_RELATIVE);
|
|
11925
|
+
if (canonical2 !== null) {
|
|
11926
|
+
paths.push(canonical2);
|
|
11927
11927
|
}
|
|
11928
11928
|
if (paths.length === 0) {
|
|
11929
11929
|
paths.push(DEFAULT_USER_GLOBAL_FILE());
|
|
@@ -18118,6 +18118,20 @@ var CAPSULE_SCHEMA_VERSION = 3;
|
|
|
18118
18118
|
function isShortLine(value, max) {
|
|
18119
18119
|
return typeof value === "string" && value.length > 0 && value.length <= max && !value.includes("\n");
|
|
18120
18120
|
}
|
|
18121
|
+
function isPathRef(value) {
|
|
18122
|
+
return typeof value === "string" && value.length > 0 && !/\s/.test(value);
|
|
18123
|
+
}
|
|
18124
|
+
function checkPathRefList(errors, field, value, max, required) {
|
|
18125
|
+
checkList(errors, field, value, max, required);
|
|
18126
|
+
if (!Array.isArray(value)) return;
|
|
18127
|
+
if (value.some((x) => !isShortLine(x, max))) return;
|
|
18128
|
+
const bad = value.filter((x) => !isPathRef(x));
|
|
18129
|
+
if (bad.length === 0) return;
|
|
18130
|
+
const shown = bad.slice(0, 3).map((x) => JSON.stringify(String(x))).join(", ");
|
|
18131
|
+
errors.push(
|
|
18132
|
+
`${field} carries ${bad.length} entr${bad.length === 1 ? "y" : "ies"} that are prose, not path refs: ${shown}${bad.length > 3 ? ", \u2026" : ""} \u2014 write the path (src/generated/api.ts, ../other-worktree/) or drop the entry; a sentence naming a file cannot be compared against a write target, and being comparable is the whole reason this is a field rather than a line of prose`
|
|
18133
|
+
);
|
|
18134
|
+
}
|
|
18121
18135
|
function checkList(errors, field, value, max, required) {
|
|
18122
18136
|
if (value === void 0) {
|
|
18123
18137
|
if (required) errors.push(`${field} is required`);
|
|
@@ -18307,7 +18321,7 @@ function validateRecycleEnvelope(input) {
|
|
|
18307
18321
|
checkList(errors, "decisions", e["decisions"], MAX_LINE_CHARS, false);
|
|
18308
18322
|
errors.push(...decisionTagErrors(e["decisions"]));
|
|
18309
18323
|
checkList(errors, "constraints", e["constraints"], MAX_LINE_CHARS, false);
|
|
18310
|
-
|
|
18324
|
+
checkPathRefList(errors, "do_not_touch", e["do_not_touch"], MAX_REF_CHARS, false);
|
|
18311
18325
|
checkList(errors, "open_worker_envelopes", e["open_worker_envelopes"], MAX_REF_CHARS, false);
|
|
18312
18326
|
checkList(errors, "artifact_paths", e["artifact_paths"], MAX_REF_CHARS, false);
|
|
18313
18327
|
checkList(errors, "suggested_skills", e["suggested_skills"], MAX_REF_CHARS, false);
|
|
@@ -20861,11 +20875,11 @@ function refresh_precommit_hook(root) {
|
|
|
20861
20875
|
if (!current.includes(_PRECOMMIT_MARKER)) {
|
|
20862
20876
|
return null;
|
|
20863
20877
|
}
|
|
20864
|
-
const
|
|
20865
|
-
if (current ===
|
|
20878
|
+
const canonical2 = fs35.readFileSync(template, "utf-8");
|
|
20879
|
+
if (current === canonical2) {
|
|
20866
20880
|
return null;
|
|
20867
20881
|
}
|
|
20868
|
-
fs35.writeFileSync(target,
|
|
20882
|
+
fs35.writeFileSync(target, canonical2);
|
|
20869
20883
|
fs35.chmodSync(target, 493);
|
|
20870
20884
|
return target;
|
|
20871
20885
|
} catch {
|
|
@@ -21453,15 +21467,15 @@ function _load_config_fail_open() {
|
|
|
21453
21467
|
var _CODEX_PLUGIN_DATA_DIRNAME = `${CODEX_PLUGIN_ID}-${CODEX_MARKETPLACE_NAME}`;
|
|
21454
21468
|
var UPSTREAM_GATE_JOB_TITLE = "Codex Stop Gate Review";
|
|
21455
21469
|
function _workspace_state_segment(workspace_root) {
|
|
21456
|
-
let
|
|
21470
|
+
let canonical2 = workspace_root;
|
|
21457
21471
|
try {
|
|
21458
|
-
|
|
21472
|
+
canonical2 = fs37.realpathSync.native(workspace_root);
|
|
21459
21473
|
} catch {
|
|
21460
|
-
|
|
21474
|
+
canonical2 = workspace_root;
|
|
21461
21475
|
}
|
|
21462
21476
|
const slug_source = path38.basename(workspace_root) || "workspace";
|
|
21463
21477
|
const slug = slug_source.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "workspace";
|
|
21464
|
-
const hash = crypto3.createHash("sha256").update(
|
|
21478
|
+
const hash = crypto3.createHash("sha256").update(canonical2).digest("hex").slice(0, 16);
|
|
21465
21479
|
return `${slug}-${hash}`;
|
|
21466
21480
|
}
|
|
21467
21481
|
function upstream_state_dir_candidates(workspace_root) {
|
|
@@ -23913,7 +23927,7 @@ function claim_is_stale(workspace_root, slug, peer_worktree) {
|
|
|
23913
23927
|
}
|
|
23914
23928
|
const base = slug.trim().replace(/\.md$/, "");
|
|
23915
23929
|
const rel = path52.normalize(path52.join("agents", "roadmaps", `${base}.md`));
|
|
23916
|
-
const inside =
|
|
23930
|
+
const inside = path52.dirname(rel) === path52.join("agents", "roadmaps");
|
|
23917
23931
|
if (!inside || path52.isAbsolute(base)) {
|
|
23918
23932
|
return true;
|
|
23919
23933
|
}
|
|
@@ -23932,18 +23946,40 @@ function claim_is_stale(workspace_root, slug, peer_worktree) {
|
|
|
23932
23946
|
return true;
|
|
23933
23947
|
}
|
|
23934
23948
|
function session_checkout(workspace_root, payload_cwd) {
|
|
23949
|
+
const fallback = canonical(workspace_root);
|
|
23935
23950
|
const cwd = String(payload_cwd ?? "").trim();
|
|
23936
|
-
if (cwd === "") return
|
|
23951
|
+
if (cwd === "") return fallback;
|
|
23952
|
+
let start;
|
|
23937
23953
|
try {
|
|
23938
|
-
if (!fs52.statSync(cwd).isDirectory()) return
|
|
23954
|
+
if (!fs52.statSync(cwd).isDirectory()) return fallback;
|
|
23955
|
+
start = fs52.realpathSync(cwd);
|
|
23939
23956
|
} catch {
|
|
23940
|
-
return
|
|
23957
|
+
return fallback;
|
|
23941
23958
|
}
|
|
23942
|
-
|
|
23943
|
-
|
|
23959
|
+
const root = nearest_checkout_root(start);
|
|
23960
|
+
if (root === null) return fallback;
|
|
23961
|
+
const mine = git_common_dir(root);
|
|
23944
23962
|
const theirs = git_common_dir(workspace_root);
|
|
23945
|
-
if (mine === null || theirs === null || mine !== theirs) return
|
|
23946
|
-
return
|
|
23963
|
+
if (mine === null || theirs === null || mine !== theirs) return fallback;
|
|
23964
|
+
return root;
|
|
23965
|
+
}
|
|
23966
|
+
function canonical(p) {
|
|
23967
|
+
const abs = path52.resolve(p);
|
|
23968
|
+
try {
|
|
23969
|
+
return fs52.realpathSync(abs);
|
|
23970
|
+
} catch {
|
|
23971
|
+
return abs;
|
|
23972
|
+
}
|
|
23973
|
+
}
|
|
23974
|
+
function nearest_checkout_root(start) {
|
|
23975
|
+
let dir = start;
|
|
23976
|
+
for (let i = 0; i < 64; i++) {
|
|
23977
|
+
if (git_dir(dir) !== null) return dir;
|
|
23978
|
+
const up = path52.dirname(dir);
|
|
23979
|
+
if (up === dir) return null;
|
|
23980
|
+
dir = up;
|
|
23981
|
+
}
|
|
23982
|
+
return null;
|
|
23947
23983
|
}
|
|
23948
23984
|
function build_record(workspace_root, session_id, platform, started_at, now = /* @__PURE__ */ new Date()) {
|
|
23949
23985
|
const rec = {
|
|
@@ -24028,8 +24064,8 @@ function foreign_sessions_block(workspace_root, session_id, now = /* @__PURE__ *
|
|
|
24028
24064
|
);
|
|
24029
24065
|
}
|
|
24030
24066
|
if (branch_hit !== null) {
|
|
24031
|
-
const peer_tree =
|
|
24032
|
-
const same_tree =
|
|
24067
|
+
const peer_tree = canonical(branch_hit.record.worktree ?? "");
|
|
24068
|
+
const same_tree = (branch_hit.record.worktree ?? "") !== "" && peer_tree === canonical(workspace_root);
|
|
24033
24069
|
if (same_tree) {
|
|
24034
24070
|
parts.push(
|
|
24035
24071
|
"",
|
|
@@ -25793,15 +25829,15 @@ function targets_kernel_rule(filePath) {
|
|
|
25793
25829
|
if (segments.length === 0) {
|
|
25794
25830
|
return null;
|
|
25795
25831
|
}
|
|
25796
|
-
const
|
|
25797
|
-
if (!is_kernel_rule(
|
|
25832
|
+
const basename10 = segments[segments.length - 1];
|
|
25833
|
+
if (!is_kernel_rule(basename10)) {
|
|
25798
25834
|
return null;
|
|
25799
25835
|
}
|
|
25800
25836
|
const dirSegments = segments.slice(0, -1);
|
|
25801
25837
|
if (!dirSegments.includes("rules")) {
|
|
25802
25838
|
return null;
|
|
25803
25839
|
}
|
|
25804
|
-
return
|
|
25840
|
+
return basename10.replace(/\.md$/, "");
|
|
25805
25841
|
}
|
|
25806
25842
|
var _MUTATOR_VERBS = /* @__PURE__ */ new Set([
|
|
25807
25843
|
"sed",
|
|
@@ -26176,7 +26212,7 @@ import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL32 } fr
|
|
|
26176
26212
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
26177
26213
|
import { existsSync as existsSync11, statSync as statSync16, readFileSync as readFileSync27, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15 } from "node:fs";
|
|
26178
26214
|
import { homedir as homedir5 } from "node:os";
|
|
26179
|
-
import { delimiter as delimiter2, join as join26, dirname as
|
|
26215
|
+
import { delimiter as delimiter2, join as join26, dirname as dirname17 } from "node:path";
|
|
26180
26216
|
var TOKEN_KILLER_GAIN_SIGNATURE = /RTK Token Savings/;
|
|
26181
26217
|
var PROBE_TIMEOUT_MS = 3e3;
|
|
26182
26218
|
function resolveBinaryOnPath(name, pathEnv) {
|
|
@@ -26271,7 +26307,7 @@ function detectRtkCached(options = {}) {
|
|
|
26271
26307
|
};
|
|
26272
26308
|
if (detection.version !== void 0) entry.version = detection.version;
|
|
26273
26309
|
try {
|
|
26274
|
-
mkdirSync15(
|
|
26310
|
+
mkdirSync15(dirname17(file), { recursive: true });
|
|
26275
26311
|
writeFileSync13(file, `${JSON.stringify(entry, null, 2)}
|
|
26276
26312
|
`, "utf-8");
|
|
26277
26313
|
} catch {
|
|
@@ -28063,14 +28099,14 @@ function int(flags, key) {
|
|
|
28063
28099
|
return Number.isFinite(n) ? n : NaN;
|
|
28064
28100
|
}
|
|
28065
28101
|
function contentHashId(input) {
|
|
28066
|
-
const
|
|
28102
|
+
const canonical2 = JSON.stringify({
|
|
28067
28103
|
ts: input.ts,
|
|
28068
28104
|
spawn_count: input.spawn_count,
|
|
28069
28105
|
token_delta: input.token_delta,
|
|
28070
28106
|
tier_chosen: input.tier_chosen ?? null,
|
|
28071
28107
|
task_class: input.task_class ?? null
|
|
28072
28108
|
});
|
|
28073
|
-
return crypto7.createHash("sha256").update(
|
|
28109
|
+
return crypto7.createHash("sha256").update(canonical2).digest("hex").slice(0, 26).toUpperCase();
|
|
28074
28110
|
}
|
|
28075
28111
|
function main41(argv = process.argv.slice(2)) {
|
|
28076
28112
|
const flags = parseFlags(argv);
|
|
@@ -32017,6 +32053,8 @@ import * as path85 from "node:path";
|
|
|
32017
32053
|
import { fileURLToPath as fileURLToPath56, pathToFileURL as pathToFileURL50 } from "node:url";
|
|
32018
32054
|
var EXIT_ALLOW27 = 0;
|
|
32019
32055
|
var EXIT_BLOCK5 = 1;
|
|
32056
|
+
var BLOCKED_BY_MARKER = /<!--\s*blocked-by:\s*\S[^>]*-->/;
|
|
32057
|
+
var LEDGER_TAIL_MAX_BYTES = 512 * 1024;
|
|
32020
32058
|
var EVENTS_RELPATH = path85.join(
|
|
32021
32059
|
"agents",
|
|
32022
32060
|
"runtime",
|
|
@@ -32027,10 +32065,14 @@ var STATE_DIR_REL = path85.join("agents", "runtime", "state");
|
|
|
32027
32065
|
var MAX_ITERATIONS = 25;
|
|
32028
32066
|
var WALL_CLOCK_CAP_MS = 4 * 60 * 60 * 1e3;
|
|
32029
32067
|
var STALL_WINDOW = 3;
|
|
32068
|
+
var ABSENT_CONFIRM_FIRES = 2;
|
|
32030
32069
|
var DUPLICATE_WINDOW_MS = 60 * 1e3;
|
|
32031
|
-
function isDuplicateFire(state, turnOrdinal, openCount, nowMs) {
|
|
32070
|
+
function isDuplicateFire(state, turnOrdinal, openCount, nowMs, roadmapSource) {
|
|
32032
32071
|
if (state === null) return false;
|
|
32033
32072
|
if (state.last_turn !== turnOrdinal) return false;
|
|
32073
|
+
if (state.history_source !== void 0 && roadmapSource !== void 0 && state.history_source !== roadmapSource) {
|
|
32074
|
+
return false;
|
|
32075
|
+
}
|
|
32034
32076
|
if (state.history.length === 0 || state.history[state.history.length - 1] !== openCount) {
|
|
32035
32077
|
return false;
|
|
32036
32078
|
}
|
|
@@ -32072,7 +32114,7 @@ function scanOpenSteps(text) {
|
|
|
32072
32114
|
}
|
|
32073
32115
|
const full = step.join("\n");
|
|
32074
32116
|
const body = m[1];
|
|
32075
|
-
if (
|
|
32117
|
+
if (BLOCKED_BY_MARKER.test(body)) {
|
|
32076
32118
|
blocked += 1;
|
|
32077
32119
|
continue;
|
|
32078
32120
|
}
|
|
@@ -32096,13 +32138,13 @@ function extractVerify(stepText) {
|
|
|
32096
32138
|
if (backticked !== null) return backticked[1].trim() || null;
|
|
32097
32139
|
return null;
|
|
32098
32140
|
}
|
|
32099
|
-
function ladder(state, openCount, nowMs, caps = {
|
|
32141
|
+
function ladder(state, openCount, nowMs, blockedCount, caps = {
|
|
32100
32142
|
maxIterations: MAX_ITERATIONS,
|
|
32101
32143
|
wallClockMs: WALL_CLOCK_CAP_MS,
|
|
32102
32144
|
stallWindow: STALL_WINDOW
|
|
32103
32145
|
}) {
|
|
32104
32146
|
if (state.halted) return state.halted;
|
|
32105
|
-
if (openCount === 0) return "complete";
|
|
32147
|
+
if (openCount === 0) return blockedCount > 0 ? "blocked" : "complete";
|
|
32106
32148
|
if (state.iterations >= caps.maxIterations) return "halt-max-iterations";
|
|
32107
32149
|
const started = Date.parse(state.started_at);
|
|
32108
32150
|
if (Number.isFinite(started) && nowMs - started >= caps.wallClockMs) {
|
|
@@ -32114,10 +32156,57 @@ function ladder(state, openCount, nowMs, caps = {
|
|
|
32114
32156
|
}
|
|
32115
32157
|
return "engage";
|
|
32116
32158
|
}
|
|
32117
|
-
function stateRelPath(runId) {
|
|
32159
|
+
function stateRelPath(runId, slug) {
|
|
32160
|
+
const safeRun = runId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
32161
|
+
const safeSlug = slug.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
32162
|
+
return path85.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
|
|
32163
|
+
}
|
|
32164
|
+
function legacyStateRelPath(runId) {
|
|
32118
32165
|
const safe = runId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
32119
32166
|
return path85.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
|
|
32120
32167
|
}
|
|
32168
|
+
function readRunState(workspaceRoot2, runId, slug) {
|
|
32169
|
+
const keyedFile = path85.join(workspaceRoot2, stateRelPath(runId, slug));
|
|
32170
|
+
const keyed = readState4(keyedFile);
|
|
32171
|
+
if (keyed !== null) return { state: keyed, from: "keyed", keyedFile };
|
|
32172
|
+
if (fileExists(keyedFile)) {
|
|
32173
|
+
return { state: null, from: "keyed", keyedFile };
|
|
32174
|
+
}
|
|
32175
|
+
const legacy = readState4(path85.join(workspaceRoot2, legacyStateRelPath(runId)));
|
|
32176
|
+
if (legacy === null) return { state: null, from: "none", keyedFile };
|
|
32177
|
+
if (legacy.roadmap !== void 0 && legacy.roadmap !== slug) {
|
|
32178
|
+
return { state: null, from: "none", keyedFile };
|
|
32179
|
+
}
|
|
32180
|
+
return { state: legacy, from: "legacy", keyedFile };
|
|
32181
|
+
}
|
|
32182
|
+
function writeState3(file, state) {
|
|
32183
|
+
try {
|
|
32184
|
+
fs84.mkdirSync(path85.dirname(file), { recursive: true });
|
|
32185
|
+
fs84.writeFileSync(file, `${JSON.stringify(state)}
|
|
32186
|
+
`, "utf8");
|
|
32187
|
+
return true;
|
|
32188
|
+
} catch {
|
|
32189
|
+
return false;
|
|
32190
|
+
}
|
|
32191
|
+
}
|
|
32192
|
+
function clearRunState(workspaceRoot2, runId, keyedFile, adoptedLegacy) {
|
|
32193
|
+
try {
|
|
32194
|
+
fs84.rmSync(keyedFile, { force: true });
|
|
32195
|
+
} catch {
|
|
32196
|
+
}
|
|
32197
|
+
if (!adoptedLegacy) return;
|
|
32198
|
+
try {
|
|
32199
|
+
fs84.rmSync(path85.join(workspaceRoot2, legacyStateRelPath(runId)), { force: true });
|
|
32200
|
+
} catch {
|
|
32201
|
+
}
|
|
32202
|
+
}
|
|
32203
|
+
function fileExists(p) {
|
|
32204
|
+
try {
|
|
32205
|
+
return fs84.statSync(p).isFile();
|
|
32206
|
+
} catch {
|
|
32207
|
+
return false;
|
|
32208
|
+
}
|
|
32209
|
+
}
|
|
32121
32210
|
function readState4(file) {
|
|
32122
32211
|
try {
|
|
32123
32212
|
const parsed = JSON.parse(fs84.readFileSync(file, "utf8"));
|
|
@@ -32138,6 +32227,18 @@ function readState4(file) {
|
|
|
32138
32227
|
if (typeof o["last_engaged_at"] === "string") {
|
|
32139
32228
|
rec.last_engaged_at = o["last_engaged_at"];
|
|
32140
32229
|
}
|
|
32230
|
+
if (typeof o["history_source"] === "string") {
|
|
32231
|
+
rec.history_source = o["history_source"];
|
|
32232
|
+
}
|
|
32233
|
+
if (typeof o["roadmap"] === "string") {
|
|
32234
|
+
rec.roadmap = o["roadmap"];
|
|
32235
|
+
}
|
|
32236
|
+
if (typeof o["absent_fires"] === "number" && Number.isFinite(o["absent_fires"])) {
|
|
32237
|
+
rec.absent_fires = o["absent_fires"];
|
|
32238
|
+
}
|
|
32239
|
+
if (o["inert_reported"] === true) {
|
|
32240
|
+
rec.inert_reported = true;
|
|
32241
|
+
}
|
|
32141
32242
|
const halted = o["halted"];
|
|
32142
32243
|
if (typeof halted === "string" && HALT_ACTIONS.includes(halted)) {
|
|
32143
32244
|
rec.halted = halted;
|
|
@@ -32147,14 +32248,93 @@ function readState4(file) {
|
|
|
32147
32248
|
return null;
|
|
32148
32249
|
}
|
|
32149
32250
|
}
|
|
32150
|
-
function
|
|
32251
|
+
function normalizeDir(p) {
|
|
32252
|
+
const abs = path85.resolve(p);
|
|
32253
|
+
try {
|
|
32254
|
+
return fs84.realpathSync(abs);
|
|
32255
|
+
} catch {
|
|
32256
|
+
return abs;
|
|
32257
|
+
}
|
|
32258
|
+
}
|
|
32259
|
+
function normalizeFile(p) {
|
|
32260
|
+
const abs = path85.resolve(p);
|
|
32261
|
+
return path85.join(normalizeDir(path85.dirname(abs)), path85.basename(abs));
|
|
32262
|
+
}
|
|
32263
|
+
function provenance(workspaceRoot2, claimPath, sessionRoot, sessionCwd) {
|
|
32264
|
+
const reader = normalizeDir(workspaceRoot2);
|
|
32265
|
+
const writer = normalizeDir(sessionRoot);
|
|
32151
32266
|
return {
|
|
32152
|
-
workspace_root:
|
|
32153
|
-
|
|
32154
|
-
|
|
32155
|
-
|
|
32267
|
+
workspace_root: reader,
|
|
32268
|
+
session_root: writer,
|
|
32269
|
+
// Empty when the host sent no `cwd` at all, which is a different fact
|
|
32270
|
+
// from a `cwd` that failed resolution — the first says the host is
|
|
32271
|
+
// silent, the second says the session sat somewhere `session_checkout`
|
|
32272
|
+
// would not trust. Both are readable; neither is guessed.
|
|
32273
|
+
//
|
|
32274
|
+
// Trimmed with the SAME rule `session_checkout` applies to the same
|
|
32275
|
+
// string (round 3 finding 6). Without it a whitespace-padded value
|
|
32276
|
+
// validated fine there and was `path.resolve`d here against the reader's
|
|
32277
|
+
// cwd, fabricating a path that is neither `session_root` nor under it —
|
|
32278
|
+
// precisely the shape the docblock above says no healthy resolution
|
|
32279
|
+
// produces, so a healthy line read as degraded. A whitespace-only value
|
|
32280
|
+
// now reads as host silence, which is what it is.
|
|
32281
|
+
session_cwd: sessionCwd.trim() === "" ? "" : normalizeDir(sessionCwd.trim()),
|
|
32282
|
+
git_dir: git_dir(writer) ?? "",
|
|
32283
|
+
git_common_dir: git_common_dir(writer) ?? "",
|
|
32284
|
+
claim_path: normalizeFile(claimPath)
|
|
32156
32285
|
};
|
|
32157
32286
|
}
|
|
32287
|
+
function resolveRoadmap(sessionRoot, workspaceRoot2, slug) {
|
|
32288
|
+
const dirRel = path85.join("agents", "roadmaps");
|
|
32289
|
+
const stem = slug.trim().replace(/\.md$/, "");
|
|
32290
|
+
const rel = path85.join(dirRel, `${stem}.md`);
|
|
32291
|
+
const norm = path85.normalize(rel);
|
|
32292
|
+
if (path85.dirname(norm) !== dirRel) return null;
|
|
32293
|
+
if (sessionRoot !== workspaceRoot2 && isDirectory(path85.join(sessionRoot, dirRel))) {
|
|
32294
|
+
return path85.join(sessionRoot, norm);
|
|
32295
|
+
}
|
|
32296
|
+
return path85.join(normalizeDir(workspaceRoot2), norm);
|
|
32297
|
+
}
|
|
32298
|
+
function isDirectory(p) {
|
|
32299
|
+
try {
|
|
32300
|
+
return fs84.statSync(p).isDirectory();
|
|
32301
|
+
} catch {
|
|
32302
|
+
return false;
|
|
32303
|
+
}
|
|
32304
|
+
}
|
|
32305
|
+
function eventAlreadyLogged(workspaceRoot2, runId, slug, event) {
|
|
32306
|
+
try {
|
|
32307
|
+
const file = path85.join(workspaceRoot2, EVENTS_RELPATH);
|
|
32308
|
+
const size = fs84.statSync(file).size;
|
|
32309
|
+
const start = Math.max(0, size - LEDGER_TAIL_MAX_BYTES);
|
|
32310
|
+
const fd = fs84.openSync(file, "r");
|
|
32311
|
+
let text;
|
|
32312
|
+
try {
|
|
32313
|
+
const buf = Buffer.alloc(size - start);
|
|
32314
|
+
const read = fs84.readSync(fd, buf, 0, buf.length, start);
|
|
32315
|
+
text = buf.subarray(0, read).toString("utf8");
|
|
32316
|
+
} finally {
|
|
32317
|
+
fs84.closeSync(fd);
|
|
32318
|
+
}
|
|
32319
|
+
for (const line of text.split("\n")) {
|
|
32320
|
+
if (line === "") continue;
|
|
32321
|
+
let rec;
|
|
32322
|
+
try {
|
|
32323
|
+
rec = JSON.parse(line);
|
|
32324
|
+
} catch {
|
|
32325
|
+
continue;
|
|
32326
|
+
}
|
|
32327
|
+
if (rec === null || typeof rec !== "object") continue;
|
|
32328
|
+
const o = rec;
|
|
32329
|
+
if (o["event"] === event && o["run_id"] === runId && o["roadmap"] === slug) {
|
|
32330
|
+
return true;
|
|
32331
|
+
}
|
|
32332
|
+
}
|
|
32333
|
+
return false;
|
|
32334
|
+
} catch {
|
|
32335
|
+
return false;
|
|
32336
|
+
}
|
|
32337
|
+
}
|
|
32158
32338
|
function appendEvent2(workspaceRoot2, record) {
|
|
32159
32339
|
try {
|
|
32160
32340
|
const file = path85.join(workspaceRoot2, EVENTS_RELPATH);
|
|
@@ -32191,12 +32371,57 @@ function main55() {
|
|
|
32191
32371
|
const claim = resolve_claim(workspaceRoot2, sessionId2 || null);
|
|
32192
32372
|
if (claim === null) return EXIT_ALLOW27;
|
|
32193
32373
|
const slug = claim.slug;
|
|
32194
|
-
const
|
|
32195
|
-
|
|
32196
|
-
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32374
|
+
const sessionRoot = session_checkout(
|
|
32375
|
+
workspaceRoot2,
|
|
32376
|
+
str10(payload["cwd"])
|
|
32377
|
+
);
|
|
32378
|
+
const roadmapPath2 = resolveRoadmap(sessionRoot, workspaceRoot2, slug);
|
|
32379
|
+
const runId = deriveSessionKey(sessionId2 || "unknown-session");
|
|
32380
|
+
let roadmapFile = null;
|
|
32381
|
+
let roadmapText = null;
|
|
32382
|
+
if (roadmapPath2 !== null) {
|
|
32383
|
+
try {
|
|
32384
|
+
roadmapText = fs84.readFileSync(roadmapPath2, "utf8");
|
|
32385
|
+
roadmapFile = roadmapPath2;
|
|
32386
|
+
} catch {
|
|
32387
|
+
roadmapText = null;
|
|
32388
|
+
}
|
|
32389
|
+
}
|
|
32390
|
+
if (roadmapText === null || roadmapFile === null) {
|
|
32391
|
+
const runState = readRunState(workspaceRoot2, runId, slug);
|
|
32392
|
+
const driven = runState.state;
|
|
32393
|
+
if (driven === null && runState.from === "none") return EXIT_ALLOW27;
|
|
32394
|
+
if (driven?.halted !== void 0) return EXIT_ALLOW27;
|
|
32395
|
+
const absenceRoots = provenance(
|
|
32396
|
+
workspaceRoot2,
|
|
32397
|
+
claim.path,
|
|
32398
|
+
sessionRoot,
|
|
32399
|
+
str10(payload["cwd"])
|
|
32400
|
+
);
|
|
32401
|
+
absenceRoots["roadmap_path"] = roadmapPath2;
|
|
32402
|
+
const absentFires = (driven?.absent_fires ?? 0) + 1;
|
|
32403
|
+
const firstAbsence = driven === null ? !eventAlreadyLogged(workspaceRoot2, runId, slug, "halt-roadmap-absent") : absentFires === 1;
|
|
32404
|
+
if (firstAbsence) {
|
|
32405
|
+
appendEvent2(workspaceRoot2, {
|
|
32406
|
+
event: "halt-roadmap-absent",
|
|
32407
|
+
run_id: runId,
|
|
32408
|
+
roadmap: slug,
|
|
32409
|
+
// `null` when the state file exists but could not be parsed.
|
|
32410
|
+
// Reported as null rather than as 0, which would claim a fact the
|
|
32411
|
+
// file no longer carries.
|
|
32412
|
+
iterations: driven?.iterations ?? null,
|
|
32413
|
+
absent_fires: driven === null ? null : absentFires,
|
|
32414
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32415
|
+
...absenceRoots
|
|
32416
|
+
});
|
|
32417
|
+
}
|
|
32418
|
+
if (driven === null) return EXIT_ALLOW27;
|
|
32419
|
+
if (absentFires < ABSENT_CONFIRM_FIRES) {
|
|
32420
|
+
driven.absent_fires = absentFires;
|
|
32421
|
+
writeState3(runState.keyedFile, driven);
|
|
32422
|
+
return EXIT_ALLOW27;
|
|
32423
|
+
}
|
|
32424
|
+
clearRunState(workspaceRoot2, runId, runState.keyedFile, runState.from === "legacy");
|
|
32200
32425
|
return EXIT_ALLOW27;
|
|
32201
32426
|
}
|
|
32202
32427
|
if (parseExecutionMode(roadmapText) !== "autonomous") return EXIT_ALLOW27;
|
|
@@ -32205,7 +32430,29 @@ function main55() {
|
|
|
32205
32430
|
);
|
|
32206
32431
|
if (!transcriptPath) return EXIT_ALLOW27;
|
|
32207
32432
|
try {
|
|
32208
|
-
if (fs84.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES)
|
|
32433
|
+
if (fs84.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
|
|
32434
|
+
const inert = readRunState(workspaceRoot2, runId, slug);
|
|
32435
|
+
if (inert.state !== null && inert.state.inert_reported !== true) {
|
|
32436
|
+
const inertRoots = provenance(
|
|
32437
|
+
workspaceRoot2,
|
|
32438
|
+
claim.path,
|
|
32439
|
+
sessionRoot,
|
|
32440
|
+
str10(payload["cwd"])
|
|
32441
|
+
);
|
|
32442
|
+
inertRoots["roadmap_path"] = roadmapFile;
|
|
32443
|
+
appendEvent2(workspaceRoot2, {
|
|
32444
|
+
event: "inert-transcript-over-cap",
|
|
32445
|
+
run_id: runId,
|
|
32446
|
+
roadmap: slug,
|
|
32447
|
+
iterations: inert.state.iterations,
|
|
32448
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32449
|
+
...inertRoots
|
|
32450
|
+
});
|
|
32451
|
+
inert.state.inert_reported = true;
|
|
32452
|
+
writeState3(inert.keyedFile, inert.state);
|
|
32453
|
+
}
|
|
32454
|
+
return EXIT_ALLOW27;
|
|
32455
|
+
}
|
|
32209
32456
|
} catch {
|
|
32210
32457
|
return EXIT_ALLOW27;
|
|
32211
32458
|
}
|
|
@@ -32217,7 +32464,13 @@ function main55() {
|
|
|
32217
32464
|
} catch {
|
|
32218
32465
|
return EXIT_ALLOW27;
|
|
32219
32466
|
}
|
|
32220
|
-
const
|
|
32467
|
+
const roots = provenance(
|
|
32468
|
+
workspaceRoot2,
|
|
32469
|
+
claim.path,
|
|
32470
|
+
sessionRoot,
|
|
32471
|
+
str10(payload["cwd"])
|
|
32472
|
+
);
|
|
32473
|
+
roots["roadmap_path"] = roadmapFile;
|
|
32221
32474
|
if (refusedThisTurn(workspaceRoot2, sessionId2, turnOrdinal)) {
|
|
32222
32475
|
appendEvent2(workspaceRoot2, {
|
|
32223
32476
|
event: "deferred-quality-gate",
|
|
@@ -32229,47 +32482,55 @@ function main55() {
|
|
|
32229
32482
|
});
|
|
32230
32483
|
return EXIT_ALLOW27;
|
|
32231
32484
|
}
|
|
32232
|
-
const
|
|
32233
|
-
const
|
|
32485
|
+
const mainState = readRunState(workspaceRoot2, runId, slug);
|
|
32486
|
+
const stateFile4 = mainState.keyedFile;
|
|
32487
|
+
const prev = mainState.state;
|
|
32234
32488
|
const state = prev ?? {
|
|
32235
32489
|
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32236
32490
|
iterations: 0,
|
|
32237
32491
|
last_turn: -1,
|
|
32238
|
-
history: []
|
|
32492
|
+
history: [],
|
|
32493
|
+
roadmap: slug
|
|
32239
32494
|
};
|
|
32495
|
+
state.roadmap = slug;
|
|
32496
|
+
delete state.absent_fires;
|
|
32240
32497
|
const scan = scanOpenSteps(roadmapText);
|
|
32241
|
-
if (isDuplicateFire(prev, turnOrdinal, scan.open, Date.now())) {
|
|
32498
|
+
if (isDuplicateFire(prev, turnOrdinal, scan.open, Date.now(), roadmapFile)) {
|
|
32242
32499
|
process.stderr.write(_continuationText(slug, scan, state.iterations));
|
|
32243
32500
|
return EXIT_BLOCK5;
|
|
32244
32501
|
}
|
|
32245
|
-
|
|
32502
|
+
if (state.history_source !== roadmapFile) {
|
|
32503
|
+
state.history = [];
|
|
32504
|
+
state.history_source = roadmapFile;
|
|
32505
|
+
}
|
|
32506
|
+
const action = ladder(state, scan.open, Date.now(), scan.blocked);
|
|
32246
32507
|
if (action !== "engage") {
|
|
32247
|
-
|
|
32248
|
-
|
|
32249
|
-
|
|
32250
|
-
|
|
32251
|
-
|
|
32252
|
-
|
|
32253
|
-
|
|
32254
|
-
|
|
32255
|
-
|
|
32256
|
-
|
|
32257
|
-
|
|
32508
|
+
const alreadyStamped = prev?.halted !== void 0;
|
|
32509
|
+
const alreadyBlocked = action === "blocked" && eventAlreadyLogged(workspaceRoot2, runId, slug, "blocked");
|
|
32510
|
+
if (!alreadyStamped && !alreadyBlocked) {
|
|
32511
|
+
appendEvent2(workspaceRoot2, {
|
|
32512
|
+
event: action,
|
|
32513
|
+
run_id: runId,
|
|
32514
|
+
roadmap: slug,
|
|
32515
|
+
turn: turnOrdinal,
|
|
32516
|
+
iterations: state.iterations,
|
|
32517
|
+
open: scan.open,
|
|
32518
|
+
blocked: scan.blocked,
|
|
32519
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32520
|
+
...roots
|
|
32521
|
+
});
|
|
32522
|
+
}
|
|
32258
32523
|
if (action === "complete") {
|
|
32259
|
-
|
|
32260
|
-
|
|
32261
|
-
|
|
32262
|
-
|
|
32524
|
+
clearRunState(workspaceRoot2, runId, stateFile4, mainState.from === "legacy");
|
|
32525
|
+
return EXIT_ALLOW27;
|
|
32526
|
+
}
|
|
32527
|
+
if (action === "blocked") {
|
|
32528
|
+
clearRunState(workspaceRoot2, runId, stateFile4, mainState.from === "legacy");
|
|
32263
32529
|
return EXIT_ALLOW27;
|
|
32264
32530
|
}
|
|
32265
32531
|
if (!state.halted) {
|
|
32266
32532
|
state.halted = action;
|
|
32267
|
-
|
|
32268
|
-
fs84.mkdirSync(path85.dirname(stateFile4), { recursive: true });
|
|
32269
|
-
fs84.writeFileSync(stateFile4, `${JSON.stringify(state)}
|
|
32270
|
-
`, "utf8");
|
|
32271
|
-
} catch {
|
|
32272
|
-
}
|
|
32533
|
+
writeState3(stateFile4, state);
|
|
32273
32534
|
}
|
|
32274
32535
|
return EXIT_ALLOW27;
|
|
32275
32536
|
}
|
|
@@ -32277,11 +32538,7 @@ function main55() {
|
|
|
32277
32538
|
state.last_turn = turnOrdinal;
|
|
32278
32539
|
state.history.push(scan.open);
|
|
32279
32540
|
state.last_engaged_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
32280
|
-
|
|
32281
|
-
fs84.mkdirSync(path85.dirname(stateFile4), { recursive: true });
|
|
32282
|
-
fs84.writeFileSync(stateFile4, `${JSON.stringify(state)}
|
|
32283
|
-
`, "utf8");
|
|
32284
|
-
} catch {
|
|
32541
|
+
if (!writeState3(stateFile4, state)) {
|
|
32285
32542
|
return EXIT_ALLOW27;
|
|
32286
32543
|
}
|
|
32287
32544
|
appendEvent2(workspaceRoot2, {
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"artefact_count": 609,
|
|
4
4
|
"scanner_version": "de0a22b4ac4c"
|
|
5
5
|
},
|
|
6
|
-
"generated_at": "2026-08-
|
|
6
|
+
"generated_at": "2026-08-20",
|
|
7
7
|
"package": {
|
|
8
8
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) \u2014 every claim machine-checked, including \"zero runtime daemon\".",
|
|
9
9
|
"homepage": "https://event4u-app.github.io/agent-config",
|
|
10
10
|
"name": "@event4u/agent-config",
|
|
11
11
|
"repository": "https://github.com/event4u-app/agent-config",
|
|
12
|
-
"version": "14.
|
|
12
|
+
"version": "14.6.0"
|
|
13
13
|
},
|
|
14
14
|
"registries": [
|
|
15
15
|
{
|
package/dist/mcp/server.json
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"transport": {
|
|
10
10
|
"type": "stdio"
|
|
11
11
|
},
|
|
12
|
-
"version": "14.
|
|
12
|
+
"version": "14.6.0"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"repository": {
|
|
16
16
|
"source": "github",
|
|
17
17
|
"url": "https://github.com/event4u-app/agent-config"
|
|
18
18
|
},
|
|
19
|
-
"version": "14.
|
|
19
|
+
"version": "14.6.0"
|
|
20
20
|
}
|