archgraph-argo 0.10.40 → 0.10.42
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.
|
@@ -7,7 +7,7 @@ applyTo: "**"
|
|
|
7
7
|
<WakeupGuideline>
|
|
8
8
|
STEP 0 — UNCONDITIONAL STARTUP GATE. This applies to the very first message of every session, including greetings, casual chat, and questions; it may never be skipped, deferred, or treated as optional.
|
|
9
9
|
1. Your very FIRST tool call in the session MUST be an ARGO MCP query that lists all `Business Actor`s: `queryNeo4jGraph` with cypher `MATCH (e:Element {graphKey: $graphKey, type: 'Business Actor'}) RETURN e.id, e.name, e.description ORDER BY e.name`. Identify which `Business Actor` you are. If you are not sure, consult your human partner to confirm your role before doing anything else.
|
|
10
|
-
2. Restore your
|
|
10
|
+
2. Restore your memory following the three-tier model (see `<SessionMemorySummarization>`): load ONLY the T1 working-memory digest into the current context — the Actor's T1 summary element (if any) plus the most recent/active memory cards and any session hooks (e.g. unfinished items from the last session). Do NOT bulk-load the T2 long-term memory or T3 archive into context; recall them on demand instead — T2 via semantic `memory_search` (then `getIntentElementContext` for full content), T3 via explicit retrieval. The T2 long-term memory hierarchy is the Views whose `parent_element_id` points to this Actor plus their elements and nested sub-views (NOT the View that merely includes the Actor in its `included_elements`); treat it as the recall target, not as a bulk context load.
|
|
11
11
|
3. If the `agent` attribute of the confirmed Actor differs from your current Agent type, switch to that Agent type, or delegate to an Agent of that type per `<CoperationGuideline>` item 2.
|
|
12
12
|
4. If the ARGO MCP is unavailable or errors, state that explicitly to the user before doing anything else. Only after completing this gate may you respond to the user or take any other action.
|
|
13
13
|
</WakeupGuideline>
|
|
@@ -103,22 +103,28 @@ Every repository change MUST be classified into exactly one tier BEFORE implemen
|
|
|
103
103
|
</CapabilityDelegationGuideline>
|
|
104
104
|
|
|
105
105
|
<SessionMemorySummarization>
|
|
106
|
-
|
|
107
|
-
1.
|
|
108
|
-
2.
|
|
109
|
-
|
|
110
|
-
- If this session's work belongs to a `Business Actor` role, write it into the long-term memory sub-views mounted under that Actor (the Views whose `parent_element_id` points to this Actor, NOT the View that merely contains the Actor itself; see `<CoperationGuideline>` item 3);
|
|
111
|
-
4. The summary must be concise and de-duplicated: prefer updating existing memory files and only create new ones when necessary; do not copy redundant process content verbatim from the session into long-term memory.
|
|
106
|
+
Long-term memory capture follows a three-tier model: T1 working memory (the Actor's session-summary element, idempotently overwritten), T2 long-term memory (the Actor's LTM sub-view hierarchy), and T3 archive (move-only). Two capture paths:
|
|
107
|
+
1. Milestone immediate writes are the RELIABLE BACKBONE — see `<MemoryTriggerTiming>`. Never defer critical content (pitfalls, decisions, commit registrations) to session end.
|
|
108
|
+
2. The session summary is OPPORTUNISTIC and IDEMPOTENT. You MUST NOT rely on precisely detecting when a session ends — the LLM cannot reliably predict the human partner ending the session. Instead, write the session summary when either: (a) the human partner explicitly signals wrap-up (e.g. "done", "summarize", "wrap up"); or (b) you have finished the latest request and the turn is ending naturally. Write it into the Actor's T1 working-memory element by OVERWRITING that single element (never append), so repeated triggers only update it and write amplification stays bounded. If the final summary is missed, the milestone immediate writes already preserve all critical content.
|
|
109
|
+
Produce a structured summary containing at least: this session's goal, completed key progress, key decisions and their reasons, remaining issues and TODOs, and reusable experience and lessons. Write it into the Actor's memory: the session summary goes to the T1 working-memory element; long-term capture goes to the T2 LTM sub-view hierarchy mounted under that Actor (the Views whose `parent_element_id` points to this Actor, NOT the View that merely contains the Actor itself; see `<CoperationGuideline>` item 3). Keep the summary concise and de-duplicated: prefer updating existing memory and only create new entries when necessary; do not copy redundant process content verbatim.
|
|
112
110
|
</SessionMemorySummarization>
|
|
113
111
|
|
|
114
112
|
<MemoryTriggerTiming>
|
|
115
|
-
|
|
113
|
+
Long-term memory writes are primarily triggered IMMEDIATELY at the following moments — this is the reliable backbone and MUST NOT be deferred to session end:
|
|
116
114
|
1. Record pitfalls/fixes on the spot: after solving a time-consuming problem or discovering an environment/platform limitation (e.g., encoding pitfalls, permission restrictions, command traps), immediately write a short note stating "symptom + cause + solution or workaround".
|
|
117
115
|
2. Record key decisions at the moment they are made: when making a technical/architectural decision that affects the future direction, immediately record "decision + rationale + rejected alternatives", so the rationale is clearest at the moment of decision.
|
|
118
116
|
3. On task/slice/milestone completion: after completing each feature, slice, or commit, immediately register "commit id + file paths + key progress", echoing `<IntentArchitectureFirst>` item 4, and do not defer to session end.
|
|
119
|
-
The above immediate records
|
|
117
|
+
The above immediate records follow the conciseness and de-duplication requirements of `<SessionMemorySummarization>`. The session-end consolidated summary is a separate, opportunistic and idempotent write (see `<SessionMemorySummarization>`), NOT the primary capture path.
|
|
120
118
|
</MemoryTriggerTiming>
|
|
121
119
|
|
|
120
|
+
<MemoryRecallGuideline>
|
|
121
|
+
Recall long-term memory in TWO steps — a compact card is a LOCATOR, never the full memory:
|
|
122
|
+
1. LOCATE: run `memory_search` (or `getSystemArchitecture` with purpose `general`) to find relevant memory by meaning. Recall uses the LOOSE memory threshold (default 0.55, configurable via `ARGO_SEMANTIC_MEMORY_THRESHOLD` / `ARGO_SEMANTIC_MEMORY_THRESHOLD_<CHANNEL>`), so paraphrased-but-relevant memory is not missed.
|
|
123
|
+
2. RETRIEVE FULL CONTENT: for each hit, call `getIntentElementContext` on the hit id to read the full element (description + attributes). Do NOT answer from the truncated card alone.
|
|
124
|
+
Threshold layering: memory recall is loose; `audit` reads are strict (default 0.8). Reject only when there are ZERO or clearly irrelevant hits — never reject a low-but-relevant score.
|
|
125
|
+
Recall target: an Actor's T2 long-term memory is its `<actor>-ltm-001` view hierarchy; T3 archive (`<actor>-archive-001`) is read by explicit retrieval. Recall on demand — never bulk-load memory into context.
|
|
126
|
+
</MemoryRecallGuideline>
|
|
127
|
+
|
|
122
128
|
<ToolsGuideline>
|
|
123
129
|
You MUST read/write the intent architecture through the tools provided by the ARGO MCP server; direct modification of the intent architecture source file is forbidden:
|
|
124
130
|
1. getSystemArchitecture: semantically read the architecture — MUST supply query.purpose + query.intent (semantic retrieval per <QueryPriorityGuideline>); an omitted-query full read is a last resort, not the default.
|
|
@@ -155,7 +155,7 @@ const TOOLS = [
|
|
|
155
155
|
},
|
|
156
156
|
{
|
|
157
157
|
name: 'updateArchitectureElement',
|
|
158
|
-
description: 'Use for one global element metadata patch. Does not change view membership. Element id and type are immutable; remove and re-add to change them. patch.attributes is a targeted merge by
|
|
158
|
+
description: 'Use for one global element metadata patch. Does not change view membership. Element id and type are immutable; remove and re-add to change them. patch.attributes is a targeted merge: single-valued attributes upsert by name; multi-valued ledgers (e.g. commit) upsert by name+value — a new value appends a new entry, re-registering the same value updates its description; {name, op:"remove"} (optionally with value) deletes the matching entries; attributes NOT mentioned are preserved — updating one attribute never wipes out the others.',
|
|
159
159
|
inputSchema: {
|
|
160
160
|
type: 'object',
|
|
161
161
|
required: ['id', 'patch'],
|
|
@@ -248,7 +248,7 @@ const TOOLS = [
|
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
name: 'updateArchitectureElement',
|
|
251
|
-
description: 'Use for one global element metadata patch. Does not change view membership. Element id and type are immutable; remove and re-add to change them. patch.attributes is a targeted merge by
|
|
251
|
+
description: 'Use for one global element metadata patch. Does not change view membership. Element id and type are immutable; remove and re-add to change them. patch.attributes is a targeted merge: single-valued attributes upsert by name; multi-valued ledgers (e.g. commit) upsert by name+value — a new value appends a new entry, re-registering the same value updates its description; {name, op:"remove"} (optionally with value) deletes the matching entries; attributes NOT mentioned are preserved — updating one attribute never wipes out the others. Set dryRun to preview without writing.',
|
|
252
252
|
inputSchema: {
|
|
253
253
|
type: 'object',
|
|
254
254
|
required: ['id', 'patch'],
|
|
@@ -1031,17 +1031,33 @@ function buildNativeSubgraph(document, includedElementIds, includedRelationshipI
|
|
|
1031
1031
|
return { elements, relationships, views };
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
/**
|
|
1035
|
+
* Attribute names that are MULTI-VALUED ledgers (many attributes share the same
|
|
1036
|
+
* `name` but carry distinct `value`s). The canonical example is the `commit`
|
|
1037
|
+
* ledger: an element accumulates one `{ name: 'commit', value: <sha> }` per
|
|
1038
|
+
* commit. For these, a patch entry upserts by (name, value) — a new value
|
|
1039
|
+
* APPENDS a new entry, re-registering the same value updates its description.
|
|
1040
|
+
*/
|
|
1041
|
+
const MULTI_VALUE_ATTRIBUTE_NAMES = new Set(['commit']);
|
|
1042
|
+
|
|
1034
1043
|
/**
|
|
1035
1044
|
* Merge a targeted attribute patch into the element's existing attributes.
|
|
1036
1045
|
*
|
|
1037
1046
|
* Each patch entry is an object with a non-empty `name`:
|
|
1038
|
-
* - `{ name, op: 'remove' }`
|
|
1039
|
-
*
|
|
1047
|
+
* - `{ name, op: 'remove' }` / `{ name, value, op: 'remove' }`
|
|
1048
|
+
* -> remove matching attribute(s); with `value`, only the exact entry.
|
|
1049
|
+
* - `{ name, value }` / `{ name, value, description }` -> upsert.
|
|
1050
|
+
*
|
|
1051
|
+
* Upsert semantics:
|
|
1052
|
+
* - Multi-valued ledgers (e.g. `commit`): match by (name, value). Same value
|
|
1053
|
+
* -> update description in place; new value -> APPEND a new entry.
|
|
1054
|
+
* - Single-valued attributes (e.g. `deliveryStatus`): match by name and
|
|
1055
|
+
* update value/description in place; absent -> append.
|
|
1040
1056
|
*
|
|
1041
1057
|
* Attributes NOT mentioned in the patch are preserved. This avoids the
|
|
1042
1058
|
* full-array replacement footgun where updating one attribute would wipe out the
|
|
1043
1059
|
* rest (e.g. a stale deliveryStatus being re-written when registering a commit
|
|
1044
|
-
* attribute).
|
|
1060
|
+
* attribute), while still letting the commit ledger accumulate entries.
|
|
1045
1061
|
*/
|
|
1046
1062
|
function mergeAttributesPatch(existing, patchEntries) {
|
|
1047
1063
|
const result = Array.isArray(existing)
|
|
@@ -1055,21 +1071,37 @@ function mergeAttributesPatch(existing, patchEntries) {
|
|
|
1055
1071
|
throw new Error('patch.attributes entries must have a non-empty string name');
|
|
1056
1072
|
}
|
|
1057
1073
|
if (entry.op === 'remove') {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1074
|
+
// Remove ALL matching entries; when a value is given, restrict to that
|
|
1075
|
+
// exact (name, value) entry so a single ledger line can be removed.
|
|
1076
|
+
for (let i = result.length - 1; i >= 0; i -= 1) {
|
|
1077
|
+
const attr = result[i];
|
|
1078
|
+
const nameMatches = attr.name === entry.name;
|
|
1079
|
+
const valueMatches = !Object.prototype.hasOwnProperty.call(entry, 'value') || attr.value === entry.value;
|
|
1080
|
+
if (nameMatches && valueMatches) result.splice(i, 1);
|
|
1061
1081
|
}
|
|
1062
1082
|
continue;
|
|
1063
1083
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
if (
|
|
1067
|
-
|
|
1084
|
+
if (MULTI_VALUE_ATTRIBUTE_NAMES.has(entry.name)) {
|
|
1085
|
+
const index = result.findIndex(attr => attr.name === entry.name && attr.value === entry.value);
|
|
1086
|
+
if (index >= 0) {
|
|
1087
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'description')) result[index].description = entry.description;
|
|
1088
|
+
} else {
|
|
1089
|
+
const newAttribute = { name: entry.name };
|
|
1090
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'value')) newAttribute.value = entry.value;
|
|
1091
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'description')) newAttribute.description = entry.description;
|
|
1092
|
+
result.push(newAttribute);
|
|
1093
|
+
}
|
|
1068
1094
|
} else {
|
|
1069
|
-
const
|
|
1070
|
-
if (
|
|
1071
|
-
|
|
1072
|
-
|
|
1095
|
+
const index = result.findIndex(attr => attr.name === entry.name);
|
|
1096
|
+
if (index >= 0) {
|
|
1097
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'value')) result[index].value = entry.value;
|
|
1098
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'description')) result[index].description = entry.description;
|
|
1099
|
+
} else {
|
|
1100
|
+
const newAttribute = { name: entry.name };
|
|
1101
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'value')) newAttribute.value = entry.value;
|
|
1102
|
+
if (Object.prototype.hasOwnProperty.call(entry, 'description')) newAttribute.description = entry.description;
|
|
1103
|
+
result.push(newAttribute);
|
|
1104
|
+
}
|
|
1073
1105
|
}
|
|
1074
1106
|
}
|
|
1075
1107
|
return result;
|
package/package.json
CHANGED