@lmzhen/dsh-evolution-core 0.30.23 → 0.30.25
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/lib/index.js +58 -3
- package/lib/types/frontmatter.d.ts +19 -0
- package/lib/types/frontmatter.js +27 -0
- package/lib/types/params.js +1 -0
- package/lib/types/run-registry.d.ts +2 -2
- package/lib/types/run-registry.js +1 -1
- package/lib/types/skill-store.d.ts +2 -1
- package/lib/types/skill-store.js +2 -1
- package/lib/types/unit-transaction.js +3 -1
- package/package.json +1 -1
- package/persisted-write-inventory.json +0 -9
package/lib/index.js
CHANGED
|
@@ -1214,7 +1214,7 @@ var UnitTransactions = class {
|
|
|
1214
1214
|
this.now = options.now ?? (() => Date.now());
|
|
1215
1215
|
}
|
|
1216
1216
|
unitId(plan) {
|
|
1217
|
-
return plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
|
|
1217
|
+
return plan.unitId ?? plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
|
|
1218
1218
|
}
|
|
1219
1219
|
async snapshot(plan, unitId, planDigest) {
|
|
1220
1220
|
const targetBefore = await this.options.backend.readSkill(plan.target);
|
|
@@ -2968,6 +2968,43 @@ function shrinksOverLimit(next, current, limit) {
|
|
|
2968
2968
|
if (current === null || current === void 0 || !exceedsContentLimit(current, limit)) return false;
|
|
2969
2969
|
return skillMdOnDisk(next).length < skillMdOnDisk(current).length;
|
|
2970
2970
|
}
|
|
2971
|
+
/**
|
|
2972
|
+
* Synthesize a missing SKILL.md header at the write boundary.
|
|
2973
|
+
*
|
|
2974
|
+
* A model-authored create/update whose body starts with `# Title` is valid Markdown but the
|
|
2975
|
+
* skill writer rejects it before any content check. Repair only the truly headerless shape: an
|
|
2976
|
+
* existing fence is passed through byte-identical, even when it is malformed, so this helper
|
|
2977
|
+
* cannot mask a header error that the validator should report. The caller owns the audit notice.
|
|
2978
|
+
* @param content - the model-authored SKILL.md text.
|
|
2979
|
+
* @param name - the validated skill name used for the `name:` field.
|
|
2980
|
+
* @param description - optional description; otherwise derived from the first heading/prose.
|
|
2981
|
+
* @returns the write text and whether a header was synthesized.
|
|
2982
|
+
*/
|
|
2983
|
+
function ensureSkillFrontmatter(content, name, description) {
|
|
2984
|
+
if (frontmatterBlock(content) !== null || content.trimStart().startsWith("---")) return {
|
|
2985
|
+
content,
|
|
2986
|
+
repaired: false
|
|
2987
|
+
};
|
|
2988
|
+
const body = content.replace(/^\uFEFF/, "").replace(/^(?:[ \t]*\r?\n)+/, "");
|
|
2989
|
+
const heading = /^#{1,6}\s+(.+?)\s*$/m.exec(body)?.[1];
|
|
2990
|
+
const firstLine = body.split(/\r?\n/).map((line) => line.trim()).find((line) => line !== "" && !line.startsWith("#")) ?? "";
|
|
2991
|
+
const source = (description?.trim() || heading || firstLine || name).replace(/\s+/g, " ").trim();
|
|
2992
|
+
const clipped = source.length > 58 ? source.slice(0, 57) + "…" : source;
|
|
2993
|
+
const summary = /[.。!?!?]$/.test(clipped) ? clipped : clipped + ".";
|
|
2994
|
+
const encoded = yamlPlainScalarNeedsQuotes(summary) ? JSON.stringify(summary) : summary;
|
|
2995
|
+
return {
|
|
2996
|
+
content: [
|
|
2997
|
+
"---",
|
|
2998
|
+
`name: ${name}`,
|
|
2999
|
+
`description: ${encoded}`,
|
|
3000
|
+
"version: 0.1.0",
|
|
3001
|
+
"author: Hermes",
|
|
3002
|
+
"---",
|
|
3003
|
+
""
|
|
3004
|
+
].join("\n") + "\n" + body,
|
|
3005
|
+
repaired: true
|
|
3006
|
+
};
|
|
3007
|
+
}
|
|
2971
3008
|
function validateFrontmatter(content, expectedName, limits = DEFAULT_SKILL_LIMITS, current) {
|
|
2972
3009
|
const parsed = parseFrontmatter(content);
|
|
2973
3010
|
if (!parsed) return "SKILL.md 必须以 `---` 行开头,用另一个完全相同的 `---` 行结束 frontmatter(只容忍结尾的 `\\r`),并在其下包含正文。";
|
|
@@ -6493,7 +6530,8 @@ function runsFile(home) {
|
|
|
6493
6530
|
const TERMINAL = new Set([
|
|
6494
6531
|
"succeeded",
|
|
6495
6532
|
"failed",
|
|
6496
|
-
"cancelled"
|
|
6533
|
+
"cancelled",
|
|
6534
|
+
"interrupted"
|
|
6497
6535
|
]);
|
|
6498
6536
|
/**
|
|
6499
6537
|
* Parse an index body into records.
|
|
@@ -12250,6 +12288,7 @@ var SkillLibrary = class {
|
|
|
12250
12288
|
return rollbackMessage(result.message, stuck);
|
|
12251
12289
|
}
|
|
12252
12290
|
}
|
|
12291
|
+
await this.foldArchivedUsage(sources, (/* @__PURE__ */ new Date()).toISOString());
|
|
12253
12292
|
await plan.onPhase?.("sources-archived");
|
|
12254
12293
|
await plan.onPhase?.("unit-written");
|
|
12255
12294
|
return {
|
|
@@ -13953,6 +13992,22 @@ const PARAM_EXPOSURE = Object.freeze([
|
|
|
13953
13992
|
values: "",
|
|
13954
13993
|
card: "evolution-review"
|
|
13955
13994
|
},
|
|
13995
|
+
{
|
|
13996
|
+
id: "reviewNotice",
|
|
13997
|
+
group: "review",
|
|
13998
|
+
tier: "E3",
|
|
13999
|
+
authority: "cordis",
|
|
14000
|
+
owner: "evolution-review",
|
|
14001
|
+
applies: "live",
|
|
14002
|
+
docAnchor: "PARAMETERS.md#review",
|
|
14003
|
+
summary: "Deliver result notices into the parent conversation.",
|
|
14004
|
+
label: "结果通知",
|
|
14005
|
+
hint: "关闭后检查结果不再写进对话;检查本身照常运行,结果留在审计记录里。",
|
|
14006
|
+
control: "switch",
|
|
14007
|
+
unit: "",
|
|
14008
|
+
values: "",
|
|
14009
|
+
card: "evolution-review"
|
|
14010
|
+
},
|
|
13956
14011
|
{
|
|
13957
14012
|
id: "reviewProvider",
|
|
13958
14013
|
group: "review",
|
|
@@ -15827,4 +15882,4 @@ function isIgnorableEvent(event) {
|
|
|
15827
15882
|
return classifySessionEvent(event) !== "model";
|
|
15828
15883
|
}
|
|
15829
15884
|
//#endregion
|
|
15830
|
-
export { AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, BASELINE_ACTION, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEDUP_MAX_PAIR_COMPARISONS, DEDUP_SIMILARITY_THRESHOLD, DEFAULT_ADMISSION, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_PROBE_TIMEOUT_MS, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_RUN_RECORDS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DEFAULT_WRITE_CONFIRM_MODE, DEFAULT_WRITE_CONFIRM_TIMEOUT_SECONDS, DIAGNOSTICS_FACT_KEYS, DIAGNOSTICS_RUNTIME_KEYS, DIAGNOSTICS_VIEW_SCHEMA_VERSION, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_PRESET_IDS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, FUZZY_MAX_PATTERN_CHARS, FUZZY_MAX_WORK, HEALTH_STAMP_RE, HISTORY_DIR, HISTORY_INDEX_VERSION, HOOK_LINE_RE, HOST_ROUTES, INSTANCE_KEYS, KEEP_LINE_RE, LONG_RUNS, LOW_QUALITY_THRESHOLD, MAINTAINER_PRESET_ID, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_REQUEST_BODY_BYTES, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MODEL_SESSION_EVENT_TYPES as MODEL_SESSION_EVENTS, MODEL_SESSION_EVENT_TYPES, MUTATIONS_FILE_VERSION, MemoryStore, NAMESPACE_MIGRATIONS, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_CATALOG_DESCRIPTION_DEFAULT, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, PLATFORM_LINE, PLATFORM_SERVICE_PROBES, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, READ_REQUIRED_ACTIONS, RESTRICTED_PRESET_DISPLAY, RESTRICTED_TOOLS_ROW_ID, RESTRICTOR_MODULE, RESTRUCTURE_TARGET_RE, RETENTION_FEEDBACK_KEEP_RATIO, RETENTION_FEEDBACK_MIN_CHARS, REVIEWER_PRESET_ID, RULES, RUNS_SCHEMA_VERSION, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, STORE_LEDGER, SUMMARY_DUPLICATE_HINT_THRESHOLD, SUPPORT_DIRS, SUPPORT_SPRAWL_FILES, SUPPRESSED_FILE_VERSION, SkillLibrary, TEXT_DIFF_MAX_CHARS, TEXT_DIFF_MAX_LINES, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UNIT_JOURNAL_PHASES, UNIT_JOURNAL_SCHEMA_VERSION, UNIT_STORAGE_SCHEMA_VERSION, UNTRUSTED_LINE_BREAK, UNTRUSTED_LINE_MARK, UPSTREAM_LIMIT_CHARS_PER_TOKEN, UnitTransactions, VERSION_SUMMARY_MAX_CHARS, absentHostServices, acquireTreeWriteLock, admissionVerdict, advanceReview, affinity, ageCopyKey, allowRowCollisions, anchorVerdict, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyNamespaceMigration, applyReferenceRewrite, asRecord, assertDispatchPayload, assertSkillsRootAliasRetired, assertUnitJournalTransition, assessStructureHealth, atomicWriteFiles, authoringFeedback, authorityFrom, backupsReachability, blobPath, bodyCost, buildCuratorRunReport, buildHealthBaseline, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, candidateSkills, canonicalWriteId, claimInstance, clampOnce, clampedNumber, classifyNamespaceMigration, classifySessionEvent, clearReviewChannel, collectReadSkillNames, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, countReferenceFiles, createGateSet, createSubagentChannel, daysSinceIso, declaredReportStamp, describeReferenceRewrite, diffFindings, dispatchKeyOf, dispatchStepOf, displayBodyOf, duplicateHeadings, elapsedSince, emptyRecord, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionActivityProjection, evolutionEventPayloadIssue, evolutionEvidenceProjection, evolutionHome, evolutionIoAdapter, evolutionReadsProjection, evolutionRoot, evolutionSignalsProjection, executeUnitUndo, filterUnreadSkillOps, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurnEvent, foldTurnEvents, foldUntrustedLines, frontmatterBlock, frontmatterCatalogInvalid, fuzzyPatch, getRecord, h2Sections, historyIndexFile, historyReachability, historyRoot, hostSurface, identity, idleDays, initialTurnFold, installEvolutionProjections, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isBookkeepingFrame, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isIgnorableEvent, isLandmark, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isRecord, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, isUnreadWrite, json, landmarkVerdict, latestActivityAt, latestVersionAt, lifecycleCandidate, lintBody, lintSkill, listEventArchives, liveBool, liveEnum, liveNumber, liveString, loadMutations, loadSuppressedNames, loadUsage, loadVersionContent, loadVersions, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, methodNotAllowed, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nearDuplicateSummaries, newRunRegistry, newSkillLibrary, nextHistoryIndex, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, normalizeVersionSummary, observeEvent, orderVersions, overlongLines, paramNamespace, paramRowId, paramSettingsId, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, partitionVersions, payloadText, persistedWriteSite, persistedWriteSites, pickWithPolicy, planNamespaceMigration, planReferenceRewrite, planRehoming, planUnitUndoAcross, policyStageLimits, probeAbsent, probeChannelState, probeList, probeMtime, probePresent, probeReason, probeText, probeUnknown, projectionText, protectedSkillNamesOf, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readHistoryIndex, readJsonObject, readNumberParam, readParam, readTreeLock, readUnitEvidence, readUnitIndex, readUnitJournal, readUnitReceipt, readUnitSnapshot, readingStats, recordMutation, recordVersions, redactSecrets, referencedBlobs, registerHostRoutes, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, renderLongRunTable, reportTime, reportsReachability, reportsSweepLockTarget, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, resolveUnitMembers, resolveUnitMembersFromIndexes, restructureCandidates, retainEventArchives, retirementReport, reviewPrompt, revisionAnchor, revisionAnchorOf, revisionFingerprint, revisionSupportDigest, runWriteGates, runsFile, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopeOfNearestManifest, scopedPackageName, scopedProbeReport, sessionAudited, sessionEvidenceIndex, sessionLastEventTime, sessionReadNames, sessionReadSkillNames, sessionSeesFamilyTools, sessionTurnSignals, skillLibraryUnitBackend, skillReadNameOf, skillRowCells, skillStateKey, skillWriteGateContext, skillsRoot, staleRouteStubs, subagentChannelState, supportFileReadOf, supportRefs, suppressedFile, sweepReports, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, treeLockFile, trimPatternBoundaries, unhookedSupportPointers, unitEvidenceDigest, unitEvidencePath, unitIndexPath, unitJournalPath, unitJournalPhaseRank, unitMembersAreComplete, unitReceiptPath, unitSnapshotPath, unitSnapshotsDir, unitStorageKey, unwrapLive, updateSuppressedNames, upsertUnitIndex, usageFile, usageObserved, userSetKeys, validateFrontmatter, validateRestructureTarget, validateSupportPath, valueOr, verifyPromptBundle, versionActionKind, versionRowCells, versionSummaryPrompt, versionTarget, vocabulary, withTreeWrite, withTreeWriteLock, writeDurableTmp, writePathSymbols, writeUnitEvidence, writeUnitJournal, writeUnitReceipt, writeUnitSnapshot, yamlPlainScalarNeedsQuotes };
|
|
15885
|
+
export { AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, BASELINE_ACTION, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEDUP_MAX_PAIR_COMPARISONS, DEDUP_SIMILARITY_THRESHOLD, DEFAULT_ADMISSION, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_PROBE_TIMEOUT_MS, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_RUN_RECORDS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DEFAULT_WRITE_CONFIRM_MODE, DEFAULT_WRITE_CONFIRM_TIMEOUT_SECONDS, DIAGNOSTICS_FACT_KEYS, DIAGNOSTICS_RUNTIME_KEYS, DIAGNOSTICS_VIEW_SCHEMA_VERSION, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_PRESET_IDS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, FUZZY_MAX_PATTERN_CHARS, FUZZY_MAX_WORK, HEALTH_STAMP_RE, HISTORY_DIR, HISTORY_INDEX_VERSION, HOOK_LINE_RE, HOST_ROUTES, INSTANCE_KEYS, KEEP_LINE_RE, LONG_RUNS, LOW_QUALITY_THRESHOLD, MAINTAINER_PRESET_ID, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_REQUEST_BODY_BYTES, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MODEL_SESSION_EVENT_TYPES as MODEL_SESSION_EVENTS, MODEL_SESSION_EVENT_TYPES, MUTATIONS_FILE_VERSION, MemoryStore, NAMESPACE_MIGRATIONS, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_CATALOG_DESCRIPTION_DEFAULT, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, PLATFORM_LINE, PLATFORM_SERVICE_PROBES, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, READ_REQUIRED_ACTIONS, RESTRICTED_PRESET_DISPLAY, RESTRICTED_TOOLS_ROW_ID, RESTRICTOR_MODULE, RESTRUCTURE_TARGET_RE, RETENTION_FEEDBACK_KEEP_RATIO, RETENTION_FEEDBACK_MIN_CHARS, REVIEWER_PRESET_ID, RULES, RUNS_SCHEMA_VERSION, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, STORE_LEDGER, SUMMARY_DUPLICATE_HINT_THRESHOLD, SUPPORT_DIRS, SUPPORT_SPRAWL_FILES, SUPPRESSED_FILE_VERSION, SkillLibrary, TEXT_DIFF_MAX_CHARS, TEXT_DIFF_MAX_LINES, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UNIT_JOURNAL_PHASES, UNIT_JOURNAL_SCHEMA_VERSION, UNIT_STORAGE_SCHEMA_VERSION, UNTRUSTED_LINE_BREAK, UNTRUSTED_LINE_MARK, UPSTREAM_LIMIT_CHARS_PER_TOKEN, UnitTransactions, VERSION_SUMMARY_MAX_CHARS, absentHostServices, acquireTreeWriteLock, admissionVerdict, advanceReview, affinity, ageCopyKey, allowRowCollisions, anchorVerdict, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyNamespaceMigration, applyReferenceRewrite, asRecord, assertDispatchPayload, assertSkillsRootAliasRetired, assertUnitJournalTransition, assessStructureHealth, atomicWriteFiles, authoringFeedback, authorityFrom, backupsReachability, blobPath, bodyCost, buildCuratorRunReport, buildHealthBaseline, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, candidateSkills, canonicalWriteId, claimInstance, clampOnce, clampedNumber, classifyNamespaceMigration, classifySessionEvent, clearReviewChannel, collectReadSkillNames, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, countReferenceFiles, createGateSet, createSubagentChannel, daysSinceIso, declaredReportStamp, describeReferenceRewrite, diffFindings, dispatchKeyOf, dispatchStepOf, displayBodyOf, duplicateHeadings, elapsedSince, emptyRecord, ensureSkillFrontmatter, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionActivityProjection, evolutionEventPayloadIssue, evolutionEvidenceProjection, evolutionHome, evolutionIoAdapter, evolutionReadsProjection, evolutionRoot, evolutionSignalsProjection, executeUnitUndo, filterUnreadSkillOps, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurnEvent, foldTurnEvents, foldUntrustedLines, frontmatterBlock, frontmatterCatalogInvalid, fuzzyPatch, getRecord, h2Sections, historyIndexFile, historyReachability, historyRoot, hostSurface, identity, idleDays, initialTurnFold, installEvolutionProjections, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isBookkeepingFrame, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isIgnorableEvent, isLandmark, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isRecord, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, isUnreadWrite, json, landmarkVerdict, latestActivityAt, latestVersionAt, lifecycleCandidate, lintBody, lintSkill, listEventArchives, liveBool, liveEnum, liveNumber, liveString, loadMutations, loadSuppressedNames, loadUsage, loadVersionContent, loadVersions, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, methodNotAllowed, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nearDuplicateSummaries, newRunRegistry, newSkillLibrary, nextHistoryIndex, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, normalizeVersionSummary, observeEvent, orderVersions, overlongLines, paramNamespace, paramRowId, paramSettingsId, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, partitionVersions, payloadText, persistedWriteSite, persistedWriteSites, pickWithPolicy, planNamespaceMigration, planReferenceRewrite, planRehoming, planUnitUndoAcross, policyStageLimits, probeAbsent, probeChannelState, probeList, probeMtime, probePresent, probeReason, probeText, probeUnknown, projectionText, protectedSkillNamesOf, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readHistoryIndex, readJsonObject, readNumberParam, readParam, readTreeLock, readUnitEvidence, readUnitIndex, readUnitJournal, readUnitReceipt, readUnitSnapshot, readingStats, recordMutation, recordVersions, redactSecrets, referencedBlobs, registerHostRoutes, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, renderLongRunTable, reportTime, reportsReachability, reportsSweepLockTarget, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, resolveUnitMembers, resolveUnitMembersFromIndexes, restructureCandidates, retainEventArchives, retirementReport, reviewPrompt, revisionAnchor, revisionAnchorOf, revisionFingerprint, revisionSupportDigest, runWriteGates, runsFile, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopeOfNearestManifest, scopedPackageName, scopedProbeReport, sessionAudited, sessionEvidenceIndex, sessionLastEventTime, sessionReadNames, sessionReadSkillNames, sessionSeesFamilyTools, sessionTurnSignals, skillLibraryUnitBackend, skillReadNameOf, skillRowCells, skillStateKey, skillWriteGateContext, skillsRoot, staleRouteStubs, subagentChannelState, supportFileReadOf, supportRefs, suppressedFile, sweepReports, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, treeLockFile, trimPatternBoundaries, unhookedSupportPointers, unitEvidenceDigest, unitEvidencePath, unitIndexPath, unitJournalPath, unitJournalPhaseRank, unitMembersAreComplete, unitReceiptPath, unitSnapshotPath, unitSnapshotsDir, unitStorageKey, unwrapLive, updateSuppressedNames, upsertUnitIndex, usageFile, usageObserved, userSetKeys, validateFrontmatter, validateRestructureTarget, validateSupportPath, valueOr, verifyPromptBundle, versionActionKind, versionRowCells, versionSummaryPrompt, versionTarget, vocabulary, withTreeWrite, withTreeWriteLock, writeDurableTmp, writePathSymbols, writeUnitEvidence, writeUnitJournal, writeUnitReceipt, writeUnitSnapshot, yamlPlainScalarNeedsQuotes };
|
|
@@ -153,6 +153,25 @@ export declare function exceedsContentLimit(content: string, limit: number): boo
|
|
|
153
153
|
/** S1.2: the repair path — a write that makes an already-over-limit file smaller.
|
|
154
154
|
* Only a NET SHRINK is exempt; an equal or larger write stays refused. */
|
|
155
155
|
export declare function shrinksOverLimit(next: string, current: string | null | undefined, limit: number): boolean;
|
|
156
|
+
export interface FrontmatterRepair {
|
|
157
|
+
/** The text to write: unchanged when a header was already present. */
|
|
158
|
+
readonly content: string;
|
|
159
|
+
/** True only when this call synthesized the missing header. */
|
|
160
|
+
readonly repaired: boolean;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Synthesize a missing SKILL.md header at the write boundary.
|
|
164
|
+
*
|
|
165
|
+
* A model-authored create/update whose body starts with `# Title` is valid Markdown but the
|
|
166
|
+
* skill writer rejects it before any content check. Repair only the truly headerless shape: an
|
|
167
|
+
* existing fence is passed through byte-identical, even when it is malformed, so this helper
|
|
168
|
+
* cannot mask a header error that the validator should report. The caller owns the audit notice.
|
|
169
|
+
* @param content - the model-authored SKILL.md text.
|
|
170
|
+
* @param name - the validated skill name used for the `name:` field.
|
|
171
|
+
* @param description - optional description; otherwise derived from the first heading/prose.
|
|
172
|
+
* @returns the write text and whether a header was synthesized.
|
|
173
|
+
*/
|
|
174
|
+
export declare function ensureSkillFrontmatter(content: string, name: string, description?: string): FrontmatterRepair;
|
|
156
175
|
export declare function validateFrontmatter(content: string, expectedName?: string, limits?: SkillLimits,
|
|
157
176
|
/** On-disk bytes, so a NET SHRINK of an over-limit file is allowed (S1.2). */
|
|
158
177
|
current?: string | null): string | null;
|
package/lib/types/frontmatter.js
CHANGED
|
@@ -555,6 +555,33 @@ export function shrinksOverLimit(next, current, limit) {
|
|
|
555
555
|
return false;
|
|
556
556
|
return skillMdOnDisk(next).length < skillMdOnDisk(current).length;
|
|
557
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Synthesize a missing SKILL.md header at the write boundary.
|
|
560
|
+
*
|
|
561
|
+
* A model-authored create/update whose body starts with `# Title` is valid Markdown but the
|
|
562
|
+
* skill writer rejects it before any content check. Repair only the truly headerless shape: an
|
|
563
|
+
* existing fence is passed through byte-identical, even when it is malformed, so this helper
|
|
564
|
+
* cannot mask a header error that the validator should report. The caller owns the audit notice.
|
|
565
|
+
* @param content - the model-authored SKILL.md text.
|
|
566
|
+
* @param name - the validated skill name used for the `name:` field.
|
|
567
|
+
* @param description - optional description; otherwise derived from the first heading/prose.
|
|
568
|
+
* @returns the write text and whether a header was synthesized.
|
|
569
|
+
*/
|
|
570
|
+
export function ensureSkillFrontmatter(content, name, description) {
|
|
571
|
+
// A valid header is byte-identical; a malformed fence is left for the validator to name,
|
|
572
|
+
// never silently replaced (that would hide the error and could duplicate the fence).
|
|
573
|
+
if (frontmatterBlock(content) !== null || content.trimStart().startsWith('---'))
|
|
574
|
+
return { content, repaired: false };
|
|
575
|
+
const body = content.replace(/^\uFEFF/, '').replace(/^(?:[ \t]*\r?\n)+/, '');
|
|
576
|
+
const heading = /^#{1,6}\s+(.+?)\s*$/m.exec(body)?.[1];
|
|
577
|
+
const firstLine = body.split(/\r?\n/).map(line => line.trim()).find(line => line !== '' && !line.startsWith('#')) ?? '';
|
|
578
|
+
const source = (description?.trim() || heading || firstLine || name).replace(/\s+/g, ' ').trim();
|
|
579
|
+
const clipped = source.length > AUTHORING_DESCRIPTION_BAR - 2 ? source.slice(0, AUTHORING_DESCRIPTION_BAR - 3) + '…' : source;
|
|
580
|
+
const summary = /[.。!?!?]$/.test(clipped) ? clipped : clipped + '.';
|
|
581
|
+
const encoded = yamlPlainScalarNeedsQuotes(summary) ? JSON.stringify(summary) : summary;
|
|
582
|
+
const header = ['---', `name: ${name}`, `description: ${encoded}`, 'version: 0.1.0', 'author: Hermes', '---', ''].join('\n');
|
|
583
|
+
return { content: header + '\n' + body, repaired: true };
|
|
584
|
+
}
|
|
558
585
|
export function validateFrontmatter(content, expectedName, limits = DEFAULT_SKILL_LIMITS,
|
|
559
586
|
/** On-disk bytes, so a NET SHRINK of an over-limit file is allowed (S1.2). */
|
|
560
587
|
current) {
|
package/lib/types/params.js
CHANGED
|
@@ -107,6 +107,7 @@ export const PARAM_EXPOSURE = Object.freeze([
|
|
|
107
107
|
{ id: 'reviewEnabled', group: 'review', tier: 'E3', authority: 'cordis', owner: 'evolution-review', applies: 'live', docAnchor: 'PARAMETERS.md#review', summary: 'Master switch for the review plugin.', label: '启用自动检查', hint: '关闭后不再自动回顾会话。', control: 'switch', unit: '', values: '', card: 'evolution-review' },
|
|
108
108
|
{ id: 'reviewMode', group: 'review', tier: 'E3', authority: 'cordis', owner: 'evolution-review', applies: 'live', docAnchor: 'PARAMETERS.md#review', summary: 'Run the review in the parent session (inject) or on a subagent.', label: '运行位置', hint: '在哪里运行检查:在当前会话里/交给子代理。', control: 'select', unit: '', values: 'subagent|inject', valueLabels: '交给子代理|在当前会话里', card: 'evolution-review' },
|
|
109
109
|
{ id: 'reviewWakeInject', group: 'review', tier: 'E3', authority: 'cordis', owner: 'evolution-review', applies: 'live', docAnchor: 'PARAMETERS.md#review', summary: 'Deliver the deferred review as a waking follow-up message.', label: '延后结果发提醒', hint: '会话空闲时,把延后的检查结果作为一条提醒发给你。', control: 'switch', unit: '', values: '', card: 'evolution-review' },
|
|
110
|
+
{ id: 'reviewNotice', group: 'review', tier: 'E3', authority: 'cordis', owner: 'evolution-review', applies: 'live', docAnchor: 'PARAMETERS.md#review', summary: 'Deliver result notices into the parent conversation.', label: '结果通知', hint: '关闭后检查结果不再写进对话;检查本身照常运行,结果留在审计记录里。', control: 'switch', unit: '', values: '', card: 'evolution-review' },
|
|
110
111
|
{ id: 'reviewProvider', group: 'review', tier: 'E2', authority: 'cordis', owner: 'evolution-review', applies: 'none', docAnchor: 'PARAMETERS.md#review', summary: 'LLM provider for review subagents (deployment identity).', why: 'identity' },
|
|
111
112
|
{ id: 'reviewTimeoutMs', group: 'review', tier: 'E2', authority: 'cordis', owner: 'evolution-review', applies: 'none', docAnchor: 'PARAMETERS.md#review', summary: 'Bound on one review subagent run and its write leg.', why: 'internal' },
|
|
112
113
|
{ id: 'reviewContextMessages', group: 'review', tier: 'E2', authority: 'cordis', owner: 'evolution-review', applies: 'none', docAnchor: 'PARAMETERS.md#review', summary: 'Messages of context handed to a review subagent.', why: 'internal' },
|
|
@@ -50,7 +50,7 @@ export interface RunProgress {
|
|
|
50
50
|
readonly total: number;
|
|
51
51
|
}
|
|
52
52
|
/** The four terminal-or-live states of a run. */
|
|
53
|
-
export type RunState = 'running' | 'succeeded' | 'failed' | 'cancelled';
|
|
53
|
+
export type RunState = 'running' | 'succeeded' | 'failed' | 'cancelled' | 'interrupted';
|
|
54
54
|
/** One tracked run. `resultRef` is a path to the run's report, never its content. */
|
|
55
55
|
export interface RunRecord {
|
|
56
56
|
id: string;
|
|
@@ -104,7 +104,7 @@ export interface RunHandle {
|
|
|
104
104
|
}
|
|
105
105
|
/** How a run ended, as reported by its owner. */
|
|
106
106
|
export interface RunOutcome {
|
|
107
|
-
state: 'succeeded' | 'failed' | 'cancelled';
|
|
107
|
+
state: 'succeeded' | 'failed' | 'cancelled' | 'interrupted';
|
|
108
108
|
resultRef?: string | undefined;
|
|
109
109
|
failure?: string | undefined;
|
|
110
110
|
/** @deprecated Legacy merge projection; read-only compatibility, never written. */
|
|
@@ -49,7 +49,7 @@ export const DEFAULT_RUN_RECORDS = 50;
|
|
|
49
49
|
export function runsFile(home) {
|
|
50
50
|
return join(home, 'runs.json');
|
|
51
51
|
}
|
|
52
|
-
const TERMINAL = new Set(['succeeded', 'failed', 'cancelled']);
|
|
52
|
+
const TERMINAL = new Set(['succeeded', 'failed', 'cancelled', 'interrupted']);
|
|
53
53
|
/**
|
|
54
54
|
* Parse an index body into records.
|
|
55
55
|
*
|
|
@@ -818,6 +818,7 @@ export interface NewSkillLibraryOptions {
|
|
|
818
818
|
export declare function newSkillLibrary(options: NewSkillLibraryOptions): SkillLibrary;
|
|
819
819
|
export { DEFAULT_SKILL_LIMITS, DEFAULT_CITATION_POLICY, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_SUPPORT_FILE_CHAR_POLICY, POLICY_STAGE_DEFAULTS, policyStageLimits, } from './limits.ts';
|
|
820
820
|
export type { SkillLimits, CitationPolicy, ReferenceRewritePolicy, ArchiveRetentionPolicy, SupportFileCharPolicy, PolicyStageFields, } from './limits.ts';
|
|
821
|
-
export { authoringFeedback, frontmatterBlock, frontmatterCatalogInvalid, normalizeFrontmatter, parseFrontmatter, relatedSkillNames, validateFrontmatter, yamlPlainScalarNeedsQuotes } from './frontmatter.ts';
|
|
821
|
+
export { authoringFeedback, ensureSkillFrontmatter, frontmatterBlock, frontmatterCatalogInvalid, normalizeFrontmatter, parseFrontmatter, relatedSkillNames, validateFrontmatter, yamlPlainScalarNeedsQuotes } from './frontmatter.ts';
|
|
822
|
+
export type { FrontmatterRepair } from './frontmatter.ts';
|
|
822
823
|
export type { AuthoringFeedback, Frontmatter, FrontmatterNormalizeResult, FrontmatterRead, PlatformStringSplit } from './frontmatter.ts';
|
|
823
824
|
//# sourceMappingURL=skill-store.d.ts.map
|
package/lib/types/skill-store.js
CHANGED
|
@@ -2392,6 +2392,7 @@ export class SkillLibrary {
|
|
|
2392
2392
|
return rollbackMessage(result.message, stuck);
|
|
2393
2393
|
}
|
|
2394
2394
|
}
|
|
2395
|
+
await this.foldArchivedUsage(sources, new Date().toISOString());
|
|
2395
2396
|
await plan.onPhase?.('sources-archived');
|
|
2396
2397
|
await plan.onPhase?.('unit-written');
|
|
2397
2398
|
return { ok: true, message: `已把 ${sources.join(', ')} 合并进「${target}」。`, unitId, targetPath: dir, archived, mutations: 1 + sources.length };
|
|
@@ -4007,5 +4008,5 @@ export function newSkillLibrary(options) {
|
|
|
4007
4008
|
[...(threatExemptLabels ?? [])], authority);
|
|
4008
4009
|
}
|
|
4009
4010
|
export { DEFAULT_SKILL_LIMITS, DEFAULT_CITATION_POLICY, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_SUPPORT_FILE_CHAR_POLICY, POLICY_STAGE_DEFAULTS, policyStageLimits, } from "./limits.js";
|
|
4010
|
-
export { authoringFeedback, frontmatterBlock, frontmatterCatalogInvalid, normalizeFrontmatter, parseFrontmatter, relatedSkillNames, validateFrontmatter, yamlPlainScalarNeedsQuotes } from "./frontmatter.js";
|
|
4011
|
+
export { authoringFeedback, ensureSkillFrontmatter, frontmatterBlock, frontmatterCatalogInvalid, normalizeFrontmatter, parseFrontmatter, relatedSkillNames, validateFrontmatter, yamlPlainScalarNeedsQuotes } from "./frontmatter.js";
|
|
4011
4012
|
//# sourceMappingURL=skill-store.js.map
|
|
@@ -43,7 +43,9 @@ export class UnitTransactions {
|
|
|
43
43
|
this.now = options.now ?? (() => Date.now());
|
|
44
44
|
}
|
|
45
45
|
unitId(plan) {
|
|
46
|
-
|
|
46
|
+
// DEC-D5: the caller may provide the unitId and still get idempotent prepare/commit.
|
|
47
|
+
// Deriving one remains the fallback for callers that do not.
|
|
48
|
+
return plan.unitId ?? plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
|
|
47
49
|
}
|
|
48
50
|
async snapshot(plan, unitId, planDigest) {
|
|
49
51
|
const targetBefore = await this.options.backend.readSkill(plan.target);
|
package/package.json
CHANGED
|
@@ -181,15 +181,6 @@
|
|
|
181
181
|
"state": [],
|
|
182
182
|
"note": "The merge rows and their persisted round-one decisions. One transaction per mutation; reads stay pure projections."
|
|
183
183
|
},
|
|
184
|
-
{
|
|
185
|
-
"id": "merge-gate-cache",
|
|
186
|
-
"path": "<evolutionHome>/merge/gate-cache.json",
|
|
187
|
-
"writer": "evolution-merge/src/gate-cache.ts",
|
|
188
|
-
"serializedBy": "transact",
|
|
189
|
-
"marker": "transactIo(io, gateCachePath(home)",
|
|
190
|
-
"state": [],
|
|
191
|
-
"note": "The L0-L2 gate cache. A cache is still a durable write and goes through the same transaction seam."
|
|
192
|
-
},
|
|
193
184
|
{
|
|
194
185
|
"id": "reports-retention-lock",
|
|
195
186
|
"path": "<evolutionHome>/reports/.retention",
|