feat: v2.2.194 — Post-gen Term Validator (결정론적 글로서리 검증)
v2.2.192 Terminology Dictionary 가 *instructional* 지시 (LLM 에게 표준 표기 사용 권유) 였다면, 이번엔 *deterministic* 검증 — LLM 이 지시를 안 따랐을 때 결정론적 정규식 스캔. 신규 모듈: src/agent/termValidator.ts - parseGlossary() — .astra/glossary.md 정규식 파싱 (mtime 캐시) Pattern 1: **Canonical** (X: typo1, typo2, ...) — typo 등장 시 "→ Canonical 권장" Pattern 2: H2/H3 "금지/비추/forbidden/avoid/don't" 섹션의 - ❌ "phrase" - validateTermUsage() — 정규식 스캔 + 발견 횟수 - formatTermValidatorFooter() — markdown 한 줄 footer False-positive 필터: - 한글 1음절·영문 1자·공백 포함 토큰 제외 - 영문 단어 경계 매치, 한글 substring Wiring: - agent.ts _maybeRunTermValidator — Self-Check 직후, swallow 패턴 - /glossary reload — Term Validator 캐시도 함께 비움 신규 설정: g1nation.termValidatorEnabled (기본 true) Footer 누적: - v2.2.191 🔍 Self-check (LLM 호출, opt-in) - v2.2.194 🔤 Term validator (정규식, on by default) 시너지: Terminology Dictionary(instructional, 작성 중) + Term Validator(deterministic, 작성 후) → 사용자가 .astra/glossary.md 한 곳만 관리하면 2단 자동 동작. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,15 +3,15 @@
|
||||
<!-- ASTRA:AUTO-START -->
|
||||
|
||||
## Snapshot
|
||||
- **Workspace**: `connectai` `v2.2.193` _(absolute path varies by environment; resolved from the active VS Code workspace)_
|
||||
- **Workspace**: `connectai` `v2.2.194` _(absolute path varies by environment; resolved from the active VS Code workspace)_
|
||||
- **Description**: The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.
|
||||
- **Stack**: TypeScript, Node.js, VS Code Extension, LM Studio SDK, Test runner
|
||||
- **Stats**: 416 source files, ~70,115 lines across 5 top-level modules.
|
||||
- **Stats**: 419 source files, ~70,411 lines across 5 top-level modules.
|
||||
|
||||
## Last Refresh
|
||||
- **Time**: 2026-05-29T06:58:50.818Z
|
||||
- **Time**: 2026-05-29T07:30:42.899Z
|
||||
- **Files newly analysed**: 3
|
||||
- **Files reused from cache**: 413
|
||||
- **Files reused from cache**: 416
|
||||
|
||||
## Directory Map
|
||||
```mermaid
|
||||
@@ -40,11 +40,11 @@ mindmap
|
||||
> Arrows: which top-level module imports from which.
|
||||
```mermaid
|
||||
flowchart LR
|
||||
src["src/<br/>262 files"]
|
||||
src["src/<br/>263 files"]
|
||||
media["media/<br/>6 files"]
|
||||
tests["tests/<br/>37 files"]
|
||||
core_py["core_py/<br/>6 files"]
|
||||
docs["docs/<br/>105 files"]
|
||||
docs["docs/<br/>107 files"]
|
||||
tests --> src
|
||||
```
|
||||
|
||||
@@ -67,13 +67,13 @@ flowchart LR
|
||||
|
||||
## Modules
|
||||
|
||||
### `src/` — 262 files, ~52,385 lines
|
||||
### `src/` — 263 files, ~52,640 lines
|
||||
|
||||
**Sub-directories**
|
||||
- `src/features/` (92) — Astra Office — public API. 다음 세션에서 추가될 OfficeSnapshot presenter / schema 도 같은 entry 로 노출 예정. 현재 노출: full webview panel H
|
||||
- `src/sidebar/` (35) — Brain profile lifecycle 의 pure helpers — sidebarProvider 의 add/edit/delete 흐름에서 modal UI 와 config 쓰기를 제외한 데이터 변환 만 격리. 현
|
||||
- `src/lib/` (28) — Astra Mode Architecture Context Builder. 의도: 사용자가 Astra 자체의 mode 디자인 (Guard vs Multi-Agent 가 별도 모드여야 하는지) 을 묻는 메타 질문에 답할
|
||||
- `src/agent/` (26) — Post-hoc Self-Check — 답변 완료 후 LLM 한 번 호출로 3가지 평가. 사용자 제안: "[Self-Check] 단계 — 이 답변이 사용자 질문에 직접 답하는가 / 규칙 준수 / 논리 모순 없는가".
|
||||
- `src/agent/` (27) — Post-hoc Self-Check — 답변 완료 후 LLM 한 번 호출로 3가지 평가. 사용자 제안: "[Self-Check] 단계 — 이 답변이 사용자 질문에 직접 답하는가 / 규칙 준수 / 논리 모순 없는가".
|
||||
- `src/retrieval/` (16) — Actionability Scoring — 검색 결과를 "현재 작업 상태" 신호로 재가중. 기존 TF-IDF (단어 매칭) + recency (시간) 만으로는 "지금 이 사용자가 하고 있는 작업과 직접 연결 된 문서
|
||||
- `src/core/` (15) — Astra Path Resolver (경로 해결기) Astra의 모든 데이터 파일(.astra 디렉토리)의 경로를 중앙에서 관리합니다. 확장 프로그램의 설치 경로(extensionUri) 기반으로 .astra 디렉토
|
||||
- `src/memory/` (9) — Distillation Loop — stale Episodic Memory → Long-Term "episode-digest" 승급. 배경: Episodic Memory 가 무한히 누적되면 검색 노이즈. 30일+ 지
|
||||
@@ -85,8 +85,8 @@ flowchart LR
|
||||
|
||||
**Key files**
|
||||
- `src/utils.ts` (471 lines)
|
||||
- `src/config.ts` (550 lines)
|
||||
- `src/agent.ts` (1568 lines)
|
||||
- `src/config.ts` (557 lines)
|
||||
- `src/agent.ts` (1589 lines)
|
||||
- `src/features/company/types.ts` (446 lines) — Type definitions for the 1인 기업 (One-Person Company) mode. The mode turns the user into a virtual CEO that dispatches work to a roster of specialist agents. Each turn produces a session directory conta
|
||||
- `src/core/services.ts` (176 lines)
|
||||
- `src/sidebarProvider.ts` (3186 lines)
|
||||
@@ -165,17 +165,17 @@ flowchart LR
|
||||
- `core_py/optimizer.py` (55 lines)
|
||||
- `core_py/queue_worker.py` (82 lines)
|
||||
|
||||
### `docs/` — 105 files, ~3,775 lines
|
||||
### `docs/` — 107 files, ~3,816 lines
|
||||
|
||||
**Sub-directories**
|
||||
- `docs/records/` (92) — Bug: /Volumes/Data/project/Antigravity/ConnectAI 프로젝트 코드 리뷰 해줄 수 있어? 개선할 부분이 있는지, 그러고...
|
||||
- `docs/records/` (94) — Bug: /Volumes/Data/project/Antigravity/ConnectAI 프로젝트 코드 리뷰 해줄 수 있어? 개선할 부분이 있는지, 그러고...
|
||||
- `docs/docs/` (5) — Bug: Viewed integrationretrieval.test.ts:1-59 integrationretrieval.test.ts를 통해 ...
|
||||
- `docs/Meeting/` (0)
|
||||
|
||||
**Key files**
|
||||
- `docs/TELEGRAM_REMOTE_EXECUTION_PLAN.md` (452 lines) — Telegram Remote Execution 기획서
|
||||
- `docs/AgentEngine_Architecture.md` (314 lines) — AgentEngine Architecture Document
|
||||
- `docs/records/ConnectAI/timeline.md` (227 lines) — Project Timeline
|
||||
- `docs/records/ConnectAI/timeline.md` (233 lines) — Project Timeline
|
||||
- `docs/ASTRA_OFFICE_REFACTOR.md` (198 lines) — Astra Office Refactor — Design Doc
|
||||
- `docs/EXPERIENCE_MEMORY_PLAN.md` (122 lines) — Experience Memory (Mistake / Lesson Loop) — Implementation Plan
|
||||
- `docs/records/ConnectAI/development/2026-05-02_connectai_project_knowledge_overview.md` (121 lines) — Astra Project Knowledge Overview
|
||||
@@ -232,7 +232,7 @@ flowchart LR
|
||||
- `g1nation.calendar.refresh` — Astra: Google Calendar 새로고침 📅
|
||||
- `g1nation.calendar.connectOAuth` — Astra: Google Calendar OAuth 연결 (쓰기) 🔐
|
||||
- `g1nation.devilAgent.toggle` — Astra: Toggle Devil Agent 🎭
|
||||
- **Configuration** (121 settings):
|
||||
- **Configuration** (122 settings):
|
||||
- `g1nation.multiAgentEnabled` *(boolean)* _(default: `false`)_ — Enable Multi-Agent Workflow (Planner -> Researcher -> Writer) for complex tasks.
|
||||
- `g1nation.datacollectBridgeUrl` *(string)* _(default: `"http://127.0.0.1:3002"`)_ — Wiki/Datacollect MCP Bridge URL. /research, /benchmark, /youtube chat slash commands route here. The Bridge must be running (`npm run bridge` in the Datacollect project).
|
||||
- `g1nation.datacollectSavePath` *(string)* _(default: `""`)_
|
||||
@@ -293,7 +293,7 @@ flowchart LR
|
||||
- `g1nation.embeddingBlendAlpha` *(number)* _(default: `0.5`)_ — Hybrid score blend: 0 = pure TF-IDF (sparse / keyword), 1 = pure embedding cosine (dense / semantic), 0.5 = balanced. Only used when g1nation.embeddingModel is set. Default 0.5.
|
||||
- `g1nation.conflictHighlightingEnabled` *(boolean)* _(default: `true`)_ — Conflict Surface — 검색된 출처에서 충돌/논란 신호 감지 시 [CONFLICT WARNINGS] 블록을 시스템 프롬프트에 주입. LLM 이 상충되는 관점을 명시하고 사용자 판단에 위임하도록. 기본 켜짐.
|
||||
- `g1nation.conflictSeverityThreshold` *(string)* _(default: `"medium"`)_ — Conflict 자기-신호 surface 시 최소 severity 임계. low=가장 민감(노이즈 가능), medium=균형(기본), high=강한 충돌만.
|
||||
- _…and 61 more_
|
||||
- _…and 62 more_
|
||||
|
||||
## Dependencies
|
||||
- **Runtime** (2): `@lmstudio/sdk`, `pdf-parse`
|
||||
@@ -341,7 +341,7 @@ Astra는 대표님의 명시적인 승인 하에 로컬 시스템의 강력한
|
||||
**Designed for High-Performance Decision Making.**
|
||||
Copyright (C) **g1nation**. All rights reserved.
|
||||
|
||||
_Last auto-scan: 2026-05-29T06:58:50.818Z · signature `e7ea4eff`_
|
||||
_Last auto-scan: 2026-05-29T07:30:42.899Z · signature `246e4864`_
|
||||
<!-- ASTRA:AUTO-END -->
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 1,
|
||||
"generatedAt": "2026-05-29T06:58:50.872Z",
|
||||
"generatedAt": "2026-05-29T07:30:42.949Z",
|
||||
"files": {
|
||||
"src/agent/actions/brainOps.ts": {
|
||||
"mtimeMs": 1779764602582.9768,
|
||||
@@ -316,10 +316,17 @@
|
||||
"src/agent"
|
||||
]
|
||||
},
|
||||
"src/agent/termValidator.ts": {
|
||||
"mtimeMs": 1780039129011.7288,
|
||||
"size": 8675,
|
||||
"lines": 221,
|
||||
"role": "Post-generation Term Validator — 답변 완료 후 정규식/사전 기반 결정론적 스캔. v2.2.192 의 Terminology Dictionary 가 instructional (LLM 에게 표준 표기 사용 지시) 이면, 이건 deterministic — LLM 이 지시를 안 따랐을 때 catch. Glossary 파싱 — 두 패턴 인식",
|
||||
"imports": []
|
||||
},
|
||||
"src/agent.ts": {
|
||||
"mtimeMs": 1780033640914.1235,
|
||||
"size": 85839,
|
||||
"lines": 1568,
|
||||
"mtimeMs": 1780039163639.0967,
|
||||
"size": 87154,
|
||||
"lines": 1589,
|
||||
"role": "",
|
||||
"imports": [
|
||||
"src/utils",
|
||||
@@ -391,6 +398,7 @@
|
||||
"src/agent/handlePrompt/computeBudgetedRequest",
|
||||
"src/agent/handlePrompt/processFinalAnswer",
|
||||
"src/agent/postHocSelfCheck",
|
||||
"src/agent/termValidator",
|
||||
"src/agent/handlePrompt/applyAutoContinuation",
|
||||
"src/features/approval/approvalQueue",
|
||||
"src/features/providers",
|
||||
@@ -433,9 +441,9 @@
|
||||
]
|
||||
},
|
||||
"src/config.ts": {
|
||||
"mtimeMs": 1780033618147.1584,
|
||||
"size": 30668,
|
||||
"lines": 550,
|
||||
"mtimeMs": 1780039183821.263,
|
||||
"size": 31114,
|
||||
"lines": 557,
|
||||
"role": "",
|
||||
"imports": []
|
||||
},
|
||||
@@ -1158,9 +1166,9 @@
|
||||
"imports": []
|
||||
},
|
||||
"src/features/datacollect/slashRouter.ts": {
|
||||
"mtimeMs": 1780035781878.5417,
|
||||
"size": 226019,
|
||||
"lines": 4090,
|
||||
"mtimeMs": 1780039211177.6035,
|
||||
"size": 226165,
|
||||
"lines": 4096,
|
||||
"role": "",
|
||||
"imports": [
|
||||
"src/utils",
|
||||
@@ -1170,6 +1178,7 @@
|
||||
"src/memory",
|
||||
"src/config",
|
||||
"src/retrieval/terminologyBlock",
|
||||
"src/agent/termValidator",
|
||||
"src/features/setup/datacollectSetup",
|
||||
"src/features/datacollect/prompts/synthesisPrompt",
|
||||
"src/features/datacollect/prompts/youtubePrompts",
|
||||
@@ -3348,7 +3357,7 @@
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/chronicle.config.json": {
|
||||
"mtimeMs": 1780037924615.7922,
|
||||
"mtimeMs": 1780039836702.8801,
|
||||
"size": 371,
|
||||
"lines": 11,
|
||||
"role": "JSON configuration",
|
||||
@@ -3550,6 +3559,13 @@
|
||||
"role": "ADR: 질문이 있어, 내가 당근이라는 중고 거래 사이트에서 8TB HDD를 구매했어. 안전거래 (Escrow)를 사용했어. 일단 물건을 어제 받았고, ...",
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/decisions/ADR-0029-여전히-오타가-있어-그러고-어색한-답변도-있네-오타-및-문맥-수정-사항-s-m-a-t-s-m-a-r-t-하드.md": {
|
||||
"mtimeMs": 1780038664272.424,
|
||||
"size": 2211,
|
||||
"lines": 19,
|
||||
"role": "ADR: 여전히 오타가 있어. 그러고 어색한 답변도 있네. 오타 및 문맥 수정 사항 S.M.A.T -> S.M.A.R.T: 하드디스크의 자가 진단 기능을...",
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/development/2026-05-02_answer-format-readability-tuning.md": {
|
||||
"mtimeMs": 1778028987330.4185,
|
||||
"size": 1564,
|
||||
@@ -3837,6 +3853,13 @@
|
||||
"role": "Discussion: E:\\Wiki\\connectai git에 커밋하고 푸쉬해줘.",
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/discussions/2026-05-29_진행해.md": {
|
||||
"mtimeMs": 1780039836692.6577,
|
||||
"size": 892,
|
||||
"lines": 16,
|
||||
"role": "Discussion: 진행해",
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/planning/2026-05-02_project-chronicle-guard.md": {
|
||||
"mtimeMs": 1778028987339.2349,
|
||||
"size": 3004,
|
||||
@@ -3887,9 +3910,9 @@
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/timeline.md": {
|
||||
"mtimeMs": 1780037924607.6199,
|
||||
"size": 14606,
|
||||
"lines": 227,
|
||||
"mtimeMs": 1780039836694.6646,
|
||||
"size": 14881,
|
||||
"lines": 233,
|
||||
"role": "Project Timeline",
|
||||
"imports": []
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "직답 결과 — single-pass mock 응답입니다.",
|
||||
"createdAt": 1780037632204,
|
||||
"createdAt": 1780039528659,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "---\nid: wiki_on\ndate: 2026-05-29T06:53:52.206Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\n직답 결과 — single-pass mock 응답입니다.\n\n직답 결과 — single-pass mock 응답입니다.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `0/100` | ✅ Low |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[DIRECT]** 답변 작성 중... (단일 호출 fast-path) (23ms)\n",
|
||||
"createdAt": 1780037632207,
|
||||
"result": "---\nid: wiki_on\ndate: 2026-05-29T07:25:28.661Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\n직답 결과 — single-pass mock 응답입니다.\n\n직답 결과 — single-pass mock 응답입니다.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `0/100` | ✅ Low |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[DIRECT]** 답변 작성 중... (단일 호출 fast-path) (22ms)\n",
|
||||
"createdAt": 1780039528661,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"missionId": "wiki_on",
|
||||
"status": "completed",
|
||||
"startTime": "2026-05-29T06:53:52.180Z",
|
||||
"totalElapsedMs": 28,
|
||||
"startTime": "2026-05-29T07:25:28.636Z",
|
||||
"totalElapsedMs": 26,
|
||||
"results": {
|
||||
"direct": "직답 결과 — single-pass mock 응답입니다."
|
||||
},
|
||||
@@ -12,16 +12,16 @@
|
||||
{
|
||||
"from": "idle",
|
||||
"to": "direct",
|
||||
"durationMs": 23,
|
||||
"durationMs": 22,
|
||||
"message": "답변 작성 중... (단일 호출 fast-path)",
|
||||
"ts": "2026-05-29T06:53:52.203Z"
|
||||
"ts": "2026-05-29T07:25:28.658Z"
|
||||
},
|
||||
{
|
||||
"from": "direct",
|
||||
"to": "completed",
|
||||
"durationMs": 4,
|
||||
"message": "미션 완료",
|
||||
"ts": "2026-05-29T06:53:52.207Z"
|
||||
"ts": "2026-05-29T07:25:28.662Z"
|
||||
}
|
||||
],
|
||||
"resilienceMetrics": {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "Final report with inconsistencies. This should be long enough to pass validation.",
|
||||
"createdAt": 1780037639311,
|
||||
"createdAt": 1780039534874,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "Final report with inconsistencies. This should be long enough to pass validation.",
|
||||
"createdAt": 1780037639310,
|
||||
"createdAt": 1780039534874,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "[{\"heading\":\"본문\",\"scope\":\"전체 답변\"}]",
|
||||
"createdAt": 1780037639305,
|
||||
"createdAt": 1780039534870,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.",
|
||||
"createdAt": 1780037639308,
|
||||
"createdAt": 1780039534872,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+9
-9
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"missionId": "stress_conflict_1780037639285",
|
||||
"missionId": "stress_conflict_1780039534851",
|
||||
"status": "completed",
|
||||
"startTime": "2026-05-29T06:53:59.285Z",
|
||||
"totalElapsedMs": 26,
|
||||
"startTime": "2026-05-29T07:25:34.851Z",
|
||||
"totalElapsedMs": 24,
|
||||
"results": {
|
||||
"outline": "[{\"heading\":\"본문\",\"scope\":\"전체 답변\"}]",
|
||||
"section_0": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.",
|
||||
@@ -14,30 +14,30 @@
|
||||
{
|
||||
"from": "idle",
|
||||
"to": "outline",
|
||||
"durationMs": 19,
|
||||
"durationMs": 18,
|
||||
"message": "답변 구조 잡는 중...",
|
||||
"ts": "2026-05-29T06:53:59.304Z"
|
||||
"ts": "2026-05-29T07:25:34.869Z"
|
||||
},
|
||||
{
|
||||
"from": "outline",
|
||||
"to": "section",
|
||||
"durationMs": 3,
|
||||
"durationMs": 2,
|
||||
"message": "본문 작성 중...",
|
||||
"ts": "2026-05-29T06:53:59.307Z"
|
||||
"ts": "2026-05-29T07:25:34.871Z"
|
||||
},
|
||||
{
|
||||
"from": "section",
|
||||
"to": "polish",
|
||||
"durationMs": 2,
|
||||
"message": "최종 다듬기 중...",
|
||||
"ts": "2026-05-29T06:53:59.309Z"
|
||||
"ts": "2026-05-29T07:25:34.873Z"
|
||||
},
|
||||
{
|
||||
"from": "polish",
|
||||
"to": "completed",
|
||||
"durationMs": 2,
|
||||
"message": "미션 완료",
|
||||
"ts": "2026-05-29T06:53:59.311Z"
|
||||
"ts": "2026-05-29T07:25:34.875Z"
|
||||
}
|
||||
],
|
||||
"resilienceMetrics": {
|
||||
Reference in New Issue
Block a user