@lmzhen/dsh-evolution-core 0.1.0-rc.67 → 0.1.0-rc.68
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 +85 -1
- package/lib/types/evolution-events.d.ts +43 -0
- package/lib/types/index.d.ts +1 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -716,6 +716,90 @@ function computeLifecycleTransitions(usage, config, now = /* @__PURE__ */ new Da
|
|
|
716
716
|
return result;
|
|
717
717
|
}
|
|
718
718
|
//#endregion
|
|
719
|
+
//#region lib/types/evolution-events.js
|
|
720
|
+
/**
|
|
721
|
+
* Self-evolution event log (rc.68): an append-only sidecar under
|
|
722
|
+
* `$DSH_HOME/evolution/events.json` that is the single source of truth for
|
|
723
|
+
* the self-improvement loop. Feedback increments and learn actions share one
|
|
724
|
+
* ordered timeline (`seq` is the ordering key), so "feedback before/after a
|
|
725
|
+
* learn on target X" is answerable. The aggregate `feedback.json` is a
|
|
726
|
+
* rebuildable boot cache, never the truth.
|
|
727
|
+
*
|
|
728
|
+
* The malformed-refusal posture matches the whole sidecar family (rc.65): an
|
|
729
|
+
* append NEVER rewrites a corrupt log — the bytes stay untouched.
|
|
730
|
+
*/
|
|
731
|
+
const EVENT_LOG_VERSION = 1;
|
|
732
|
+
function eventsFile(home) {
|
|
733
|
+
return join(home, "evolution", "events.json");
|
|
734
|
+
}
|
|
735
|
+
function isEventRecord(event) {
|
|
736
|
+
return typeof event === "object" && event !== null && typeof event.seq === "number";
|
|
737
|
+
}
|
|
738
|
+
function parseEventList(raw) {
|
|
739
|
+
if (raw === null) return [];
|
|
740
|
+
try {
|
|
741
|
+
const parsed = JSON.parse(raw);
|
|
742
|
+
if (!Array.isArray(parsed.events)) return [];
|
|
743
|
+
return parsed.events.filter(isEventRecord);
|
|
744
|
+
} catch {
|
|
745
|
+
return [];
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Append one event under the write lock (rc.68): `seq` = current max + 1
|
|
750
|
+
* computed inside the transact, so two processes appending concurrently never
|
|
751
|
+
* collide. A malformed log is refused (bytes preserved) and the append fails.
|
|
752
|
+
* Returns the assigned seq.
|
|
753
|
+
*/
|
|
754
|
+
async function appendEvolutionEvent(io, path, event) {
|
|
755
|
+
let assigned = 0;
|
|
756
|
+
await transactIo(io, path, (current) => {
|
|
757
|
+
if (current !== null) try {
|
|
758
|
+
JSON.parse(current);
|
|
759
|
+
} catch {
|
|
760
|
+
return Promise.resolve(current);
|
|
761
|
+
}
|
|
762
|
+
const events = parseEventList(current);
|
|
763
|
+
const maxSeq = events.reduce((max, entry) => Math.max(max, entry.seq), 0);
|
|
764
|
+
const record = {
|
|
765
|
+
...event,
|
|
766
|
+
seq: maxSeq + 1,
|
|
767
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
768
|
+
};
|
|
769
|
+
assigned = record.seq;
|
|
770
|
+
return Promise.resolve(JSON.stringify({
|
|
771
|
+
version: 1,
|
|
772
|
+
events: [...events, record]
|
|
773
|
+
}, null, 2));
|
|
774
|
+
});
|
|
775
|
+
if (assigned === 0) throw new Error(`evolution event log is malformed and was not touched: ${path}`);
|
|
776
|
+
return assigned;
|
|
777
|
+
}
|
|
778
|
+
/** Read the event log; a missing file reads as empty, malformed is flagged. */
|
|
779
|
+
async function readEvolutionEvents(io, path) {
|
|
780
|
+
const raw = await io.readText(path);
|
|
781
|
+
if (raw === null) return {
|
|
782
|
+
events: [],
|
|
783
|
+
malformed: false
|
|
784
|
+
};
|
|
785
|
+
try {
|
|
786
|
+
const parsed = JSON.parse(raw);
|
|
787
|
+
if (!Array.isArray(parsed.events)) return {
|
|
788
|
+
events: [],
|
|
789
|
+
malformed: true
|
|
790
|
+
};
|
|
791
|
+
return {
|
|
792
|
+
events: parsed.events.filter(isEventRecord),
|
|
793
|
+
malformed: false
|
|
794
|
+
};
|
|
795
|
+
} catch {
|
|
796
|
+
return {
|
|
797
|
+
events: [],
|
|
798
|
+
malformed: true
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
//#endregion
|
|
719
803
|
//#region lib/types/prompts.js
|
|
720
804
|
/**
|
|
721
805
|
* Review and curation prompts adapted from Hermes Agent
|
|
@@ -3032,4 +3116,4 @@ function evolutionHome(env = process.env) {
|
|
|
3032
3116
|
return join(env.DSH_HOME ?? join(homedir(), ".dsh"), "evolution");
|
|
3033
3117
|
}
|
|
3034
3118
|
//#endregion
|
|
3035
|
-
export { AUTHORING_DESCRIPTION_BAR, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_USER_CHAR_LIMIT, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EvolutionGateSet, LOW_QUALITY_THRESHOLD, MAX_DESCRIPTION_LENGTH, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MEMORY_REVIEW_PROMPT, MUTATIONS_FILE_VERSION, MemoryStore, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, QUALITY_WEIGHTS, SKILLS_GUIDANCE, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, applyCuratorFields, authoringFeedback, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, createGateSet, emptyRecord, evaluateThreat, evolutionHome, evolutionIoAdapter, foldCuratorFields, foldTurn, getRecord, latestActivityAt, lifecycleCandidate, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, mutateUsage, mutationsFile, nodeEvolutionIo, normalizeUsageRecord, observeEvent, parseCuratorNominations, parseFrontmatter, recordMutation, relatedSkillNames, renderCuratorReportMarkdown, resolveOrigins, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, transactIo, updateSuppressedNames, usageFile, validateFrontmatter, verifyPromptBundle };
|
|
3119
|
+
export { AUTHORING_DESCRIPTION_BAR, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_USER_CHAR_LIMIT, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_LOG_VERSION, EvolutionGateSet, LOW_QUALITY_THRESHOLD, MAX_DESCRIPTION_LENGTH, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MEMORY_REVIEW_PROMPT, MUTATIONS_FILE_VERSION, MemoryStore, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, QUALITY_WEIGHTS, SKILLS_GUIDANCE, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, appendEvolutionEvent, applyCuratorFields, authoringFeedback, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, createGateSet, emptyRecord, evaluateThreat, eventsFile, evolutionHome, evolutionIoAdapter, foldCuratorFields, foldTurn, getRecord, latestActivityAt, lifecycleCandidate, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, mutateUsage, mutationsFile, nodeEvolutionIo, normalizeUsageRecord, observeEvent, parseCuratorNominations, parseFrontmatter, readEvolutionEvents, recordMutation, relatedSkillNames, renderCuratorReportMarkdown, resolveOrigins, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, transactIo, updateSuppressedNames, usageFile, validateFrontmatter, verifyPromptBundle };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-evolution event log (rc.68): an append-only sidecar under
|
|
3
|
+
* `$DSH_HOME/evolution/events.json` that is the single source of truth for
|
|
4
|
+
* the self-improvement loop. Feedback increments and learn actions share one
|
|
5
|
+
* ordered timeline (`seq` is the ordering key), so "feedback before/after a
|
|
6
|
+
* learn on target X" is answerable. The aggregate `feedback.json` is a
|
|
7
|
+
* rebuildable boot cache, never the truth.
|
|
8
|
+
*
|
|
9
|
+
* The malformed-refusal posture matches the whole sidecar family (rc.65): an
|
|
10
|
+
* append NEVER rewrites a corrupt log — the bytes stay untouched.
|
|
11
|
+
*/
|
|
12
|
+
import { type EvolutionIoLike } from './io.ts';
|
|
13
|
+
export declare const EVENT_LOG_VERSION = 1;
|
|
14
|
+
export interface EvolutionEvent {
|
|
15
|
+
/** Global monotonic order key, assigned inside the append transact. */
|
|
16
|
+
seq: number;
|
|
17
|
+
/** ISO timestamp at append time. */
|
|
18
|
+
at: string;
|
|
19
|
+
/** Tagged-union discriminator: feedback increments vs learn actions. */
|
|
20
|
+
type: 'feedback' | 'learn';
|
|
21
|
+
target?: string | undefined;
|
|
22
|
+
kind?: 'skill' | 'session' | undefined;
|
|
23
|
+
rating?: 'positive' | 'negative' | undefined;
|
|
24
|
+
note?: string | undefined;
|
|
25
|
+
source?: string | undefined;
|
|
26
|
+
request?: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
export declare function eventsFile(home: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Append one event under the write lock (rc.68): `seq` = current max + 1
|
|
31
|
+
* computed inside the transact, so two processes appending concurrently never
|
|
32
|
+
* collide. A malformed log is refused (bytes preserved) and the append fails.
|
|
33
|
+
* Returns the assigned seq.
|
|
34
|
+
*/
|
|
35
|
+
export declare function appendEvolutionEvent(io: EvolutionIoLike, path: string, event: Omit<EvolutionEvent, 'seq' | 'at'>): Promise<number>;
|
|
36
|
+
export interface EventLogRead {
|
|
37
|
+
events: EvolutionEvent[];
|
|
38
|
+
/** True when the file existed but could not be parsed (loss case; never overwritten). */
|
|
39
|
+
malformed: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** Read the event log; a missing file reads as empty, malformed is flagged. */
|
|
42
|
+
export declare function readEvolutionEvents(io: EvolutionIoLike, path: string): Promise<EventLogRead>;
|
|
43
|
+
//# sourceMappingURL=evolution-events.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-core",
|
|
3
3
|
"description": "Shared stores, prompts, signals and lifecycle logic for the dsh-evolution plugin family (community build)",
|
|
4
|
-
"version": "0.1.0-rc.
|
|
4
|
+
"version": "0.1.0-rc.68",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|