archgraph-argo 0.24.1 → 0.24.2

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.
@@ -85,32 +85,35 @@ const CHANNELS = Object.freeze([
85
85
  indexName: 'argo_production_semantic_view_vector',
86
86
  }),
87
87
  ]);
88
+ // Project an explicit metadata allowlist instead of properties(node): Neo4j map
89
+ // projection `.*` lets an existing property win, so properties(node) / node{.*, vector:null}
90
+ // would still ship the 1536-dim vector; the read path only consumes canonicalIdentity, channel, searchText and score.
88
91
  const VECTOR_QUERY_CYPHER = [
89
92
  'CALL db.index.vector.queryNodes($indexName, $topK, $vector)',
90
93
  'YIELD node, score',
91
94
  'WHERE node.channel = $channel',
92
- 'RETURN properties(node) AS record, score',
95
+ 'RETURN {canonicalIdentity: node.canonicalIdentity, channel: node.channel, searchText: node.searchText, dimensions: node.dimensions, provider: node.provider, model: node.model, modelVersion: node.modelVersion, canonicalVersion: node.canonicalVersion, contentVersion: node.contentVersion, indexVersion: node.indexVersion} AS record, score',
93
96
  'ORDER BY score DESC',
94
97
  ].join('\n');
95
98
  const VECTOR_QUERY_CYPHER_SCOPED = [
96
99
  'CALL db.index.vector.queryNodes($indexName, $topK, $vector)',
97
100
  'YIELD node, score',
98
101
  'WHERE node.channel = $channel AND node.canonicalIdentity IN $canonicalIdentities',
99
- 'RETURN properties(node) AS record, score',
102
+ 'RETURN {canonicalIdentity: node.canonicalIdentity, channel: node.channel, searchText: node.searchText, dimensions: node.dimensions, provider: node.provider, model: node.model, modelVersion: node.modelVersion, canonicalVersion: node.canonicalVersion, contentVersion: node.contentVersion, indexVersion: node.indexVersion} AS record, score',
100
103
  'ORDER BY score DESC',
101
104
  ].join('\n');
102
105
  const LEXICAL_QUERY_CYPHER = [
103
106
  'CALL db.index.fulltext.queryNodes($indexName, $queryText, { limit: $topK })',
104
107
  'YIELD node, score',
105
108
  'WHERE node.channel = $channel',
106
- 'RETURN properties(node) AS record, score',
109
+ 'RETURN {canonicalIdentity: node.canonicalIdentity, channel: node.channel, searchText: node.searchText, dimensions: node.dimensions, provider: node.provider, model: node.model, modelVersion: node.modelVersion, canonicalVersion: node.canonicalVersion, contentVersion: node.contentVersion, indexVersion: node.indexVersion} AS record, score',
107
110
  'ORDER BY score DESC',
108
111
  ].join('\n');
109
112
  const LEXICAL_QUERY_CYPHER_SCOPED = [
110
113
  'CALL db.index.fulltext.queryNodes($indexName, $queryText, { limit: $topK })',
111
114
  'YIELD node, score',
112
115
  'WHERE node.channel = $channel AND node.canonicalIdentity IN $canonicalIdentities',
113
- 'RETURN properties(node) AS record, score',
116
+ 'RETURN {canonicalIdentity: node.canonicalIdentity, channel: node.channel, searchText: node.searchText, dimensions: node.dimensions, provider: node.provider, model: node.model, modelVersion: node.modelVersion, canonicalVersion: node.canonicalVersion, contentVersion: node.contentVersion, indexVersion: node.indexVersion} AS record, score',
114
117
  'ORDER BY score DESC',
115
118
  ].join('\n');
116
119
  const READINESS_QUERY_CYPHER = [
@@ -149,6 +152,12 @@ function resolveTopK() {
149
152
  const k = envNumber('ARGO_SEMANTIC_TOP_K', DEFAULT_TOP_K);
150
153
  return Number.isInteger(k) && k > 0 ? k : DEFAULT_TOP_K;
151
154
  }
155
+ // The single production seed gate: a retrieved record becomes a seed only when
156
+ // its TRUE vector similarity reaches the purpose-aware threshold. Exposed so
157
+ // acceptance tests exercise the exact predicate the retrieval runtime uses.
158
+ function isSeedAboveThreshold(score, threshold) {
159
+ return Number.isFinite(score) && Number.isFinite(threshold) && score >= threshold;
160
+ }
152
161
  const testCompositionStorage = new AsyncLocalStorage();
153
162
 
154
163
  function createDefaultSemanticRetrieval(dependencies = {}) {
@@ -828,7 +837,7 @@ async function exhaustChannel({
828
837
  for (const raw of newlyVisible) {
829
838
  if (accepted.length >= effectiveMax) break;
830
839
  const record = normalizeVectorRecord(raw, channel);
831
- if (record && record.score >= effectiveThreshold && !seen.has(record.id)) {
840
+ if (record && isSeedAboveThreshold(record.score, effectiveThreshold) && !seen.has(record.id)) {
832
841
  seen.add(record.id);
833
842
  accepted.push(Object.freeze(record));
834
843
  }
@@ -1238,8 +1247,11 @@ module.exports = {
1238
1247
  memoryThresholdFor,
1239
1248
  auditThresholdFor,
1240
1249
  resolveTopK,
1250
+ isSeedAboveThreshold,
1241
1251
  scopeCanonicalIdentitiesForChannel,
1242
1252
  bareCanonicalId,
1243
1253
  normalizeVectorRecord,
1254
+ exhaustChannel,
1255
+ exhaustLexicalChannel,
1244
1256
  AUDIT_PURPOSES,
1245
1257
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archgraph-argo",
3
- "version": "0.24.1",
3
+ "version": "0.24.2",
4
4
  "description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
5
5
  "license": "MIT",
6
6
  "bin": {