@liuhange/dsh-data-asset-attestation 3.1.0
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/README.md +22 -0
- package/lib/index.js +94 -0
- package/lib/policyBasis.js +17 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @liuhange/dsh-data-asset-attestation
|
|
2
|
+
|
|
3
|
+
## 功能说明
|
|
4
|
+
|
|
5
|
+
Attestation-level data quality report plugin with evidence chain hash and attestation statement
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
dsh plugin --profile web add @liuhange/dsh-data-asset-attestation
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 用法
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { apply } from '@liuhange/dsh-data-asset-attestation';
|
|
17
|
+
apply(ctx); // 注册工具: attest_data_quality
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
MIT
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export const name = '@liuhange/dsh-data-asset-attestation';
|
|
2
|
+
export const inject = ['tools'];
|
|
3
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
4
|
+
import { loadJsonConfig } from '@liuhange/dsh-data-asset-shared';
|
|
5
|
+
import { resolvePolicyBasis } from './policyBasis.js';
|
|
6
|
+
export function apply(ctx) {
|
|
7
|
+
ctx.tools.register({
|
|
8
|
+
name: 'attest_data_quality',
|
|
9
|
+
description: '生成鉴证级数据质量报告,含时间戳、证据链哈希和鉴证声明',
|
|
10
|
+
parameters: {
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
qualityScoreResult: { type: 'string', description: 'quality-score工具输出的JSON结果' },
|
|
14
|
+
assetId: { type: 'string', description: '数据资产标识(可选)' },
|
|
15
|
+
},
|
|
16
|
+
required: ['qualityScoreResult'],
|
|
17
|
+
},
|
|
18
|
+
async execute(args) {
|
|
19
|
+
try {
|
|
20
|
+
if (!args?.qualityScoreResult || typeof args.qualityScoreResult !== 'string') {
|
|
21
|
+
return JSON.stringify({ error: 'ATTESTATION_INPUT_INVALID', message: 'qualityScoreResult is required' });
|
|
22
|
+
}
|
|
23
|
+
const scoreResult = JSON.parse(args.qualityScoreResult);
|
|
24
|
+
if (scoreResult.error) {
|
|
25
|
+
return JSON.stringify({ error: 'ATTESTATION_INPUT_INVALID', message: `quality-score错误透传: ${scoreResult.error}` });
|
|
26
|
+
}
|
|
27
|
+
let rulesConfig;
|
|
28
|
+
try {
|
|
29
|
+
rulesConfig = loadJsonConfig('BUSINESS_RULES_PATH', 'config/business-rules.json', '@liuhange/dsh-data-asset-shared/config/business-rules.json');
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return JSON.stringify({ error: 'ATTESTATION_RULES_MISSING', message: '无法加载business-rules.json' });
|
|
33
|
+
}
|
|
34
|
+
const attestationConfig = rulesConfig.attestation;
|
|
35
|
+
if (!attestationConfig) {
|
|
36
|
+
return JSON.stringify({ error: 'ATTESTATION_RULES_MISSING', message: 'attestation配置段缺失' });
|
|
37
|
+
}
|
|
38
|
+
const dimensions = (scoreResult.dimensions ?? []);
|
|
39
|
+
const anomalies = locateAnomalies(dimensions, attestationConfig.severityMapping, args.assetId ?? 'unknown');
|
|
40
|
+
const evidenceChainHash = buildEvidenceChain(anomalies, scoreResult);
|
|
41
|
+
const policyBasis = resolvePolicyBasis('ATTESTATION');
|
|
42
|
+
const statement = generateStatement(anomalies, attestationConfig.statementTemplate);
|
|
43
|
+
const report = {
|
|
44
|
+
reportId: randomUUID(),
|
|
45
|
+
generatedAt: new Date().toISOString(),
|
|
46
|
+
inspector: 'dsh-data-asset-attestation',
|
|
47
|
+
inspectionMethod: '基于六维质量评分的自动化鉴证',
|
|
48
|
+
dataSampleSize: anomalies.length,
|
|
49
|
+
anomalies,
|
|
50
|
+
evidenceChainHash,
|
|
51
|
+
attestationStatement: statement,
|
|
52
|
+
policyBasis,
|
|
53
|
+
qualityScoreReference: scoreResult.timestamp ?? 'unknown',
|
|
54
|
+
disclaimer: '鉴证报告底稿,正式鉴证须由具备资质的鉴证机构出具',
|
|
55
|
+
};
|
|
56
|
+
return JSON.stringify(report, null, 2);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
return JSON.stringify({ error: 'UNKNOWN_ERROR', message: e.message });
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function locateAnomalies(dimensions, severityMapping, assetId) {
|
|
65
|
+
const anomalies = [];
|
|
66
|
+
for (const dim of dimensions) {
|
|
67
|
+
if (dim.score < 60) {
|
|
68
|
+
const deduction = 100 - dim.score;
|
|
69
|
+
let severity = 'minor';
|
|
70
|
+
if (deduction >= (severityMapping.critical ?? 20))
|
|
71
|
+
severity = 'critical';
|
|
72
|
+
else if (deduction >= (severityMapping.major ?? 10))
|
|
73
|
+
severity = 'major';
|
|
74
|
+
for (const issue of dim.issues) {
|
|
75
|
+
anomalies.push({ dimension: dim.dimension, severity, assetId, issue });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return anomalies;
|
|
80
|
+
}
|
|
81
|
+
function buildEvidenceChain(anomalies, scoreResult) {
|
|
82
|
+
try {
|
|
83
|
+
const serialized = JSON.stringify({ anomalies, scoreResult, timestamp: new Date().toISOString() });
|
|
84
|
+
return createHash('sha256').update(serialized).digest('hex');
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
return `构建失败: ${e.message}`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function generateStatement(anomalies, template) {
|
|
91
|
+
const conclusion = anomalies.length === 0 ? '数据质量符合入表要求' : '数据质量不符合入表要求,存在异常项';
|
|
92
|
+
return `${template.scope}。${template.basis}。${conclusion}。`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { loadJsonConfig } from '@liuhange/dsh-data-asset-shared';
|
|
2
|
+
export function resolvePolicyBasis(stage) {
|
|
3
|
+
try {
|
|
4
|
+
const config = loadJsonConfig('POLICY_REFS_PATH', 'config/policy-references.json', '@liuhange/dsh-data-asset-shared/config/policy-references.json');
|
|
5
|
+
const refs = config.policyReferences;
|
|
6
|
+
const stageEntry = refs?.find((s) => s.stage === stage);
|
|
7
|
+
if (!stageEntry) {
|
|
8
|
+
console.warn(`Policy stage "${stage}" not configured`);
|
|
9
|
+
return [`依据:政策依据未配置(stage=${stage})`];
|
|
10
|
+
}
|
|
11
|
+
return stageEntry.documents.map((d) => `依据:《${d.name}》(${d.docNumber})—${d.coreRequirement}`);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return ['依据:政策依据配置加载失败'];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=policyBasis.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liuhange/dsh-data-asset-attestation",
|
|
3
|
+
"description": "Attestation-level data quality report plugin with evidence chain hash and attestation statement",
|
|
4
|
+
"version": "3.1.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/liuhange789/data-asset-inspector.git",
|
|
11
|
+
"directory": "packages/data-asset/data-asset-attestation"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./src/*": "./src/*",
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"lib/**/*.js",
|
|
26
|
+
"lib/types/**/*.d.ts"
|
|
27
|
+
],
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"build": "tsc"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@deepseek-ai/cordis": "^4.0.0",
|
|
36
|
+
"@deepseek-ai/dsh-tools": "0.0.1-rc.1",
|
|
37
|
+
"@liuhange/dsh-data-asset-shared": "^3.0.0"
|
|
38
|
+
},
|
|
39
|
+
"dsh": {
|
|
40
|
+
"bundle": {
|
|
41
|
+
"patch": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"deepseek-harness",
|
|
46
|
+
"dsh-plugin",
|
|
47
|
+
"data-asset",
|
|
48
|
+
"data-asset-inspector",
|
|
49
|
+
"shujintong",
|
|
50
|
+
"数据资产",
|
|
51
|
+
"attestation",
|
|
52
|
+
"evidence-chain",
|
|
53
|
+
"quality-attestation",
|
|
54
|
+
"鉴证报告",
|
|
55
|
+
"证据链",
|
|
56
|
+
"质量鉴证"
|
|
57
|
+
],
|
|
58
|
+
"homepage": "https://github.com/liuhange789/data-asset-inspector#readme"
|
|
59
|
+
}
|