@principles/host-runtime 0.12.0 → 0.12.1

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.
@@ -146,8 +146,22 @@ export type AdmitGovernanceSignalsResult = {
146
146
  } | Degradation;
147
147
  /** Public generic intake stays Codex + explicit WorkBuddy only. */
148
148
  export declare function admitGovernanceSignals(input: AdmitGovernanceSignalsInput): AdmitGovernanceSignalsResult;
149
- /** Pure check: no DB, no filesystem, no classifier, no historical transcript. */
150
- export declare function assessWorkbuddyLiveKeyword(text: string, sessionId: string): {
149
+ /**
150
+ * AUDIT-P3-01 (2026-10-21): WorkBuddy live-keyword 检测接入共享 live 词库
151
+ * (`<workspace>/.state/correction_keywords.json`,seed ∪ learned,mtime 刷新,
152
+ * 文件缺失/损坏降级 seed-only)。返回的是完整共享 store——"只允许 high 精度
153
+ * correction 词触发自动 Pain"由 assess 的 matched 判据(isSignal && STRONG &&
154
+ * correction && matchedPrecision==='high')与 admitOne 的 isStrongHighPrecision
155
+ * 门共同强制,与 OpenClaw 检测共享同一套 precision 语义(earned-high 需
156
+ * TP≥3 且零 FP;owner_promoted/seed 需权重≥0.7)。
157
+ */
158
+ export declare function resolveSharedCorrectionKeywordStoreForDetection(workspaceDir: string): UnifiedKeywordStore;
159
+ /**
160
+ * Pure check: no DB, no classifier, no historical transcript. The optional
161
+ * store parameter is how the shared live vocabulary enters (AUDIT-P3-01);
162
+ * omitted, the check keeps the P0 four-term projection (backward compatible).
163
+ */
164
+ export declare function assessWorkbuddyLiveKeyword(text: string, sessionId: string, store?: UnifiedKeywordStore): {
151
165
  matched: boolean;
152
166
  reason: 'matched' | 'not_a_signal' | 'prompt_too_large';
153
167
  };
@@ -726,17 +726,33 @@ function workbuddyP0KeywordStore() {
726
726
  }
727
727
  return { version: seed.version, terms };
728
728
  }
729
- /** Pure check: no DB, no filesystem, no classifier, no historical transcript. */
730
- export function assessWorkbuddyLiveKeyword(text, sessionId) {
729
+ /**
730
+ * AUDIT-P3-01 (2026-10-21): WorkBuddy live-keyword 检测接入共享 live 词库
731
+ * (`<workspace>/.state/correction_keywords.json`,seed ∪ learned,mtime 刷新,
732
+ * 文件缺失/损坏降级 seed-only)。返回的是完整共享 store——"只允许 high 精度
733
+ * correction 词触发自动 Pain"由 assess 的 matched 判据(isSignal && STRONG &&
734
+ * correction && matchedPrecision==='high')与 admitOne 的 isStrongHighPrecision
735
+ * 门共同强制,与 OpenClaw 检测共享同一套 precision 语义(earned-high 需
736
+ * TP≥3 且零 FP;owner_promoted/seed 需权重≥0.7)。
737
+ */
738
+ export function resolveSharedCorrectionKeywordStoreForDetection(workspaceDir) {
739
+ return createSharedCorrectionKeywordStore({ workspaceDir }).resolve();
740
+ }
741
+ /**
742
+ * Pure check: no DB, no classifier, no historical transcript. The optional
743
+ * store parameter is how the shared live vocabulary enters (AUDIT-P3-01);
744
+ * omitted, the check keeps the P0 four-term projection (backward compatible).
745
+ */
746
+ export function assessWorkbuddyLiveKeyword(text, sessionId, store) {
731
747
  if (Buffer.byteLength(text, 'utf8') > WORKBUDDY_MAX_PROMPT_BYTES) {
732
748
  return { matched: false, reason: 'prompt_too_large' };
733
749
  }
734
- const store = workbuddyP0KeywordStore();
750
+ const resolved = store ?? workbuddyP0KeywordStore();
735
751
  // Prefer precision to recall: reject quoted/embedded/reported phrases.
736
- if (!Object.keys(store.terms).some(term => text.trimStart().toLowerCase().startsWith(term.toLowerCase()))) {
752
+ if (!Object.keys(resolved.terms).some(term => text.trimStart().toLowerCase().startsWith(term.toLowerCase()))) {
737
753
  return { matched: false, reason: 'not_a_signal' };
738
754
  }
739
- const out = collectSync(text, sessionId, store, SYNC_DETECTION_CONFIG, new Date().toISOString());
755
+ const out = collectSync(text, sessionId, resolved, SYNC_DETECTION_CONFIG, new Date().toISOString());
740
756
  const matched = out.isSignal && out.strength === 'STRONG' &&
741
757
  out.type === 'correction' && out.matchedPrecision === 'high';
742
758
  return { matched, reason: matched ? 'matched' : 'not_a_signal' };
@@ -769,7 +785,11 @@ export function admitTrustedWorkbuddyLiveCorrection(input) {
769
785
  if (prompt.trimStart().startsWith('PD记录痛苦')) {
770
786
  return { ok: false, reason: 'explicit_owner_statement_reserved', nextAction: 'Use original Owner intake; no keyword fallback.' };
771
787
  }
772
- if (!assessWorkbuddyLiveKeyword(prompt, sessionId).matched) {
788
+ // AUDIT-P3-01: 预检与准入共用同一份共享 live 词库(单一真理源)——预检命中
789
+ // 词与 admitOne 的检测判定不会漂移。自动 Pain 仍只允许 high 精度 correction
790
+ // 词(两道门各自强制),无 LLM、无 transcript 读取。
791
+ const sharedStore = resolveSharedCorrectionKeywordStoreForDetection(input.workspaceDir);
792
+ if (!assessWorkbuddyLiveKeyword(prompt, sessionId, sharedStore).matched) {
773
793
  return { ok: true, outcomes: [] };
774
794
  }
775
795
  const nativeIdentity = JSON.stringify(['workbuddy', sessionId, generationId]);
@@ -785,7 +805,7 @@ export function admitTrustedWorkbuddyLiveCorrection(input) {
785
805
  text: prompt,
786
806
  observedAt: (input.now ?? new Date()).toISOString(),
787
807
  }],
788
- keywordStore: workbuddyP0KeywordStore(),
808
+ keywordStore: sharedStore,
789
809
  ...(input.now ? { now: input.now } : {}),
790
810
  ...(input.databaseFactory ? { databaseFactory: input.databaseFactory } : {}),
791
811
  }, true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/host-runtime",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Shared host-neutral orchestration for Principles Disciple MVP-Core hook paths.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "lint": "eslint \"src/**/*.ts\""
32
32
  },
33
33
  "dependencies": {
34
- "@principles/core": "^1.295.0",
34
+ "@principles/core": "^1.295.2",
35
35
  "@principles/install-layout": "^0.4.0",
36
36
  "better-sqlite3": "^13.0.3",
37
37
  "js-yaml": "^5.4.3"