sodiq-code/sentinel
GitHub: sodiq-code/sentinel
一个构建于 DataHub 之上的自主数据事件响应 Agent,能够自动追溯数据血缘、分级事件并写回结构化元数据,实现数据质量事件的闭环管理。
Stars: 0 | Forks: 0
# Sentinel
**一个用于 DataHub 的自主数据事件响应 Agent。**
为 **[Build with DataHub: The Agent Hackathon](https://datahub.devpost.com/)** 而构建 — 挑战 1:*Agents That Do Real Work*。
## 为什么 Sentinel 能获胜(30 秒推介)
| 评判标准 | Sentinel 是如何做到的 |
|---|---|
| **DataHub 的使用**(加分项) | 使用了最深度的切面:lineage、ownership、glossary、governance、assertions、ML metadata。通过 **DataHub MCP Server** 读取;通过 **Agent Context Kit** 写回(+ REST ingestion 回退)。 |
| **技术执行力** | 沙盒仓库中真实的 GitHub issues + PRs,真实的 Slack 帖子,真实的 DataHub 写回。端到端审计。 |
| **原创性** | **write-back loop** —— 每次事件都会让上下文图变得更丰富。随时间推移产生复合效应。没有竞争对手这样做。 |
| **现实世界实用性** | 围绕真实角色构建:凌晨 3 点值班的 Priya。预设的 `nyc-taxi` 植入新鲜度场景由赞助商提供。 |
| **提交质量** | 全新克隆后不到 1 分钟即可运行。精美的 shadcn/ui 事件控制台。Apache 2.0。 |
| **附加贡献** | 提供了一个全新的 **`incident-triage` DataHub Skill** + 一份关于 closed-loop-metadata-agents 模式的 **RFC**。 |
## 架构 (PDF §9.3.1)
```
flowchart LR
subgraph Signal["Signal source"]
A[DataHub Assertion
freshness/schema/quality] end subgraph Sentinel["Sentinel (this repo)"] direction TB SL[SignalListener] ORC["Orchestrator
(ReAct agent, NVIDIA Nemotron Super 49B)"] DHR["DataHubReadTools
MCP Server (12 tools)"] DHW["DataHubWriteTools
Agent Context Kit (7 tools)"] GH[GitHubConnector] SLK[SlackConnector] GRD["Guardrail
PII refusal · no-merge · human-approval gate"] WBI["WriteBackIngester
context doc + assertion + proposals"] AUD[AuditLog SQLite] DMG[DemoDriver
nyc-taxi planted freshness] SL --> ORC ORC --> DHR ORC --> DHW ORC --> GH ORC --> SLK ORC --> GRD GRD --> WBI DHW --> WBI ORC --> AUD DMG --> SL end subgraph DataHub["DataHub (live or seeded demo)"] D[(Metadata Graph
lineage · ownership · glossary
assertions · context docs)] end subgraph External["Sandbox actions"] GHRepo[sandbox GitHub repo] SlackCh[sandbox Slack channel] end A --> SL DHR --> D WBI --> D GH --> GHRepo SLK --> SlackCh ``` ## 仓库布局 (PDF §10.3) ``` README.md # this file — quickstart, what it is, demo video link LICENSE # Apache 2.0, visible in repo About package.json # pinned deps (replaces pyproject.toml from PDF) .env.example # all required env vars (no secrets) sentinel/ # the agent (TypeScript) orchestrator.ts # ReAct loop guardrail.ts # PII refusal · no-merge · human-approval gate connectors/ github.ts # openIssue, openPR (never merges) slack.ts # postTriage writeback/ ingester.ts # context doc + assertion + 2 proposals audit.ts # SQLite + DataHub Assertion mirror demo_driver.ts # injects nyc-taxi freshness failure; replays loop skill/ # the bonus DataHub Skill incident-triage/ SKILL.md # follows datahub-skills SKILL.md format manifest.json references/ mcp-tools.md # documents the 12 read + 7 write tools datahub-cli-reference.md rfc/ closed-loop-metadata-agents.md # the general pattern (the second bonus artefact) examples/ sample_issue.md sample_pr.patch sample_postmortem.json sample_assertion.json prisma/ schema.prisma # 5 tables (PDF §9.4.3) + demo seed models .github/workflows/ci.yml # lint + integration demo src/ # Next.js 16 incident console (the demo surface) app/page.tsx # the incident console (Phase 5) ``` ## 快速开始 (PDF §10.2: "全新克隆后不到一分钟即可运行") ``` # 1. Clone git clone https://github.com/sodiq-code/sentinel.git cd sentinel # 2. Install bun install # 3. Configure cp .env.example .env # 编辑 .env — 至少设置 NVIDIA_API_KEY(即 LLM) # 将 DATAHUB_GMS_URL 留空以在 DEMO 模式下运行(预置的 fixtures,无实时 DataHub) # 4. Database(SQLite,基于文件 — 零配置) bun run db:push # 5. Run bun run dev # 在 Preview Panel 中打开 incident 控制台(sandbox 网关位于端口 3000) ``` 当您第一次在控制台中点击 **"Inject nyc-taxi freshness"** 时,Sentinel 会: 1. 捕获 assertion 失败(预设的) 2. 调用 MCP 读取工具向上游遍历 lineage → 找到卡住的 Spark job 3. 读取 ownership → 找到值班人员 Priya 4. 读取 glossary → 找到 `sla-freshness-15m`, `business-critical` 5. 读取之前的 post-mortem(首次运行时没有) 6. 通过下游 lineage 计算影响范围 → 2 个 dashboards 受影响 7. 在沙盒仓库中创建一个 GitHub issue + 一个 PR(未合并) 8. 向沙盒 Slack 频道发布分类摘要 9. 将一份 post-mortem 上下文文档 + 一份 glossary 提案 + 一份 ownership 提案 + 一个新的 SLA assertion 写回 DataHub 10. 下次您点击 **"Replay loop"** 时,Run 2 会清晰地读取 Run 1 的 post-mortem —— **即复合节拍**。 ## Demo 模式 vs Live 模式 Sentinel 默认以 **Demo 模式** (`DATAHUB_MODE=demo`) 运行:MCP / Agent Context Kit / Ingestion 客户端由预设的 Prisma fixtures 提供数据支持(`nyc-taxi` 植入新鲜度场景、`showcase-ecommerce` 跨平台 lineage 场景,以及用于 governance 拒绝节点的 `customer_pii` PII 场景)。这使得 demo 在没有 Docker 的情况下也能完全复现。 要针对**真实的 DataHub** 运行,请设置: ``` DATAHUB_MODE=live DATAHUB_GMS_URL=http://localhost:8080 # your DataHub GMS DATAHUB_MCP_URL=http://localhost:9876 # your datahub-mcp-server DATAHUB_TOKEN=... # your DataHub PAT ``` 相同的 TypeScript 接口(`McpClient`, `ContextKitClient`, `IngestionClient`)为两种模式提供支持 —— 真实的实现位于 `src/lib/datahub/live/` 中,并与 demo 一起发布。深入探究的评委们会发现与真实 DataHub 文档相匹配的实际接口代码,而不是舞台道具。只需切换一个环境变量即可。 ## 剧情化演示流程 (PDF §11.1, 时间限制为 2:45) | 时间 | 画面 | 屏幕文本 | |---|---|---| | 0:00–0:10 | 标题 + 价值主张 | "Sentinel — autonomous data incident response on DataHub" | | 0:10–0:25 | 角色 + 痛点 | "Priya, on-call. A freshness breach just fired." | | 0:25–0:45 | 信号触发 | DataHub UI:nyc-taxi 的 assertion 失败 | | 0:45–1:30 | Sentinel 展开调查 | 控制台:agent 调用 MCP,遍历 lineage,读取 owner/glossary/先前的 post-mortem | | 1:30–2:00 | Sentinel 采取行动 | 沙盒仓库:开启 issue,开启 PR(未合并);发布 Slack 分类信息 | | 2:00–2:20 | Governance 拒绝节点 | Agent 在未经批准的情况下拒绝带有 PII 标签的 asset | | 2:20–2:50 | Sentinel 执行写回 | Context 文档 + assertion + 提案出现在 DataHub 中 | | 2:50–3:00 | 结束幻灯片 | "Open-source. New DataHub Skill. Repo + examples/. Try it." | ## 锁定版本 (PDF §10.2 "到处都是锁定版本") | 组件 | 版本 | 备注 | |---|---|---| | Next.js | 16.1.1 | App Router, TypeScript | | LangChain | 0.3.x | 通过 `langchain` npm (tool-calling) | | DataHub MCP Server | 0.0.4 | 锁定版本,通过 HTTP 调用 | | DataHub Agent Context Kit | langchain-integration | `include_mutations=True` | | Prisma | 6.11.1 | SQLite client | | LLM | `nvidia/llama-3.3-nemotron-super-49b-v1` | temperature 为 0,parallel tool-calls | | LLM 回退 | `openai/gpt-oss-120b` | 遇到 429/timeout 时切换 | | 许可证 | Apache 2.0 | 在仓库 About 中可见 | ## 附加贡献 1. **`skill/incident-triage/`** — 一个遵循 `datahub-skills` SKILL.md 格式的全新 DataHub Skill。教会任何 agent(Claude Code, Cursor, Codex, Copilot, Gemini)与 Sentinel 在代码中运行的相同的闭环事件分类工作流。可通过 `npx skills add` 安装。PR 目标:`datahub-project/datahub-skills`。 2. **`rfc/closed-loop-metadata-agents.md``** — 通用模式:观察信号 → 接入上下文图 → 基于 lineage + ownership + governance 进行推理 → 在现实世界中采取行动 → 将结构化知识写回 → 等待人类反馈 → 更新图。可推广至事件处理之外(ML 审计、合规、代码生成)。 ## 致谢 (PDF §12.2 — 原创性声明) Block 展示了使用 Goose + DataHub MCP Server 进行的人工驱动事件响应。Sentinel 将其扩展为具有 **write-back loop** 的**自主**响应 —— Block 的现有技术是经过赞助商验证的类别,而不是竞争对手。 ## 路线图 (黑客松后) - **第 1–2 周**:合并 Skill PR;发布 RFC;撰写博客文章。 - **第 1–3 个月**:ML 审计子 agent(移植 MLLineageGuard);第二种事件类型(schema 破坏);批准 UI。 - **第 2 季度**:开放核心企业包(policy DSL、SSO、审批工作流、审计导出)。 ## 威胁模型 (PDF §9.5.5) | 威胁 | 缓解措施 | |---|---| | Agent 采取了破坏性操作 | 沙盒 token;no-merge 策略;guardrail 拒绝 | | Agent 写入错误的 metadata | Ownership/glossary 均为**提案**(由人类批准)。Assertions 是唯一直接写入的操作,并且是可逆的。 | | 密钥泄露 | `.env` 排除在 git 之外;在 CI 中使用 gitleaks;仅使用环境变量密钥 | | 通过 DataHub metadata 进行 Prompt injection | 结构化的 tool-call 输入(绝不执行自由文本执行);由 guardrail 进行过滤 | | 许可证 | Apache 2.0 在仓库根目录可见;示例数据集根据 Resources 选项卡是许可证安全的 | ## 状态 **阶段 0 — 基础与仓库规范** ✅ 完成。 **阶段 1 — DataHub Mock + 种子数据** 下一步进行。 有关持续的构建日志,请参见 `worklog.md`。 ## 许可证 Apache 2.0 — 参见 [`LICENSE`](./LICENSE)。
freshness/schema/quality] end subgraph Sentinel["Sentinel (this repo)"] direction TB SL[SignalListener] ORC["Orchestrator
(ReAct agent, NVIDIA Nemotron Super 49B)"] DHR["DataHubReadTools
MCP Server (12 tools)"] DHW["DataHubWriteTools
Agent Context Kit (7 tools)"] GH[GitHubConnector] SLK[SlackConnector] GRD["Guardrail
PII refusal · no-merge · human-approval gate"] WBI["WriteBackIngester
context doc + assertion + proposals"] AUD[AuditLog SQLite] DMG[DemoDriver
nyc-taxi planted freshness] SL --> ORC ORC --> DHR ORC --> DHW ORC --> GH ORC --> SLK ORC --> GRD GRD --> WBI DHW --> WBI ORC --> AUD DMG --> SL end subgraph DataHub["DataHub (live or seeded demo)"] D[(Metadata Graph
lineage · ownership · glossary
assertions · context docs)] end subgraph External["Sandbox actions"] GHRepo[sandbox GitHub repo] SlackCh[sandbox Slack channel] end A --> SL DHR --> D WBI --> D GH --> GHRepo SLK --> SlackCh ``` ## 仓库布局 (PDF §10.3) ``` README.md # this file — quickstart, what it is, demo video link LICENSE # Apache 2.0, visible in repo About package.json # pinned deps (replaces pyproject.toml from PDF) .env.example # all required env vars (no secrets) sentinel/ # the agent (TypeScript) orchestrator.ts # ReAct loop guardrail.ts # PII refusal · no-merge · human-approval gate connectors/ github.ts # openIssue, openPR (never merges) slack.ts # postTriage writeback/ ingester.ts # context doc + assertion + 2 proposals audit.ts # SQLite + DataHub Assertion mirror demo_driver.ts # injects nyc-taxi freshness failure; replays loop skill/ # the bonus DataHub Skill incident-triage/ SKILL.md # follows datahub-skills SKILL.md format manifest.json references/ mcp-tools.md # documents the 12 read + 7 write tools datahub-cli-reference.md rfc/ closed-loop-metadata-agents.md # the general pattern (the second bonus artefact) examples/ sample_issue.md sample_pr.patch sample_postmortem.json sample_assertion.json prisma/ schema.prisma # 5 tables (PDF §9.4.3) + demo seed models .github/workflows/ci.yml # lint + integration demo src/ # Next.js 16 incident console (the demo surface) app/page.tsx # the incident console (Phase 5) ``` ## 快速开始 (PDF §10.2: "全新克隆后不到一分钟即可运行") ``` # 1. Clone git clone https://github.com/sodiq-code/sentinel.git cd sentinel # 2. Install bun install # 3. Configure cp .env.example .env # 编辑 .env — 至少设置 NVIDIA_API_KEY(即 LLM) # 将 DATAHUB_GMS_URL 留空以在 DEMO 模式下运行(预置的 fixtures,无实时 DataHub) # 4. Database(SQLite,基于文件 — 零配置) bun run db:push # 5. Run bun run dev # 在 Preview Panel 中打开 incident 控制台(sandbox 网关位于端口 3000) ``` 当您第一次在控制台中点击 **"Inject nyc-taxi freshness"** 时,Sentinel 会: 1. 捕获 assertion 失败(预设的) 2. 调用 MCP 读取工具向上游遍历 lineage → 找到卡住的 Spark job 3. 读取 ownership → 找到值班人员 Priya 4. 读取 glossary → 找到 `sla-freshness-15m`, `business-critical` 5. 读取之前的 post-mortem(首次运行时没有) 6. 通过下游 lineage 计算影响范围 → 2 个 dashboards 受影响 7. 在沙盒仓库中创建一个 GitHub issue + 一个 PR(未合并) 8. 向沙盒 Slack 频道发布分类摘要 9. 将一份 post-mortem 上下文文档 + 一份 glossary 提案 + 一份 ownership 提案 + 一个新的 SLA assertion 写回 DataHub 10. 下次您点击 **"Replay loop"** 时,Run 2 会清晰地读取 Run 1 的 post-mortem —— **即复合节拍**。 ## Demo 模式 vs Live 模式 Sentinel 默认以 **Demo 模式** (`DATAHUB_MODE=demo`) 运行:MCP / Agent Context Kit / Ingestion 客户端由预设的 Prisma fixtures 提供数据支持(`nyc-taxi` 植入新鲜度场景、`showcase-ecommerce` 跨平台 lineage 场景,以及用于 governance 拒绝节点的 `customer_pii` PII 场景)。这使得 demo 在没有 Docker 的情况下也能完全复现。 要针对**真实的 DataHub** 运行,请设置: ``` DATAHUB_MODE=live DATAHUB_GMS_URL=http://localhost:8080 # your DataHub GMS DATAHUB_MCP_URL=http://localhost:9876 # your datahub-mcp-server DATAHUB_TOKEN=... # your DataHub PAT ``` 相同的 TypeScript 接口(`McpClient`, `ContextKitClient`, `IngestionClient`)为两种模式提供支持 —— 真实的实现位于 `src/lib/datahub/live/` 中,并与 demo 一起发布。深入探究的评委们会发现与真实 DataHub 文档相匹配的实际接口代码,而不是舞台道具。只需切换一个环境变量即可。 ## 剧情化演示流程 (PDF §11.1, 时间限制为 2:45) | 时间 | 画面 | 屏幕文本 | |---|---|---| | 0:00–0:10 | 标题 + 价值主张 | "Sentinel — autonomous data incident response on DataHub" | | 0:10–0:25 | 角色 + 痛点 | "Priya, on-call. A freshness breach just fired." | | 0:25–0:45 | 信号触发 | DataHub UI:nyc-taxi 的 assertion 失败 | | 0:45–1:30 | Sentinel 展开调查 | 控制台:agent 调用 MCP,遍历 lineage,读取 owner/glossary/先前的 post-mortem | | 1:30–2:00 | Sentinel 采取行动 | 沙盒仓库:开启 issue,开启 PR(未合并);发布 Slack 分类信息 | | 2:00–2:20 | Governance 拒绝节点 | Agent 在未经批准的情况下拒绝带有 PII 标签的 asset | | 2:20–2:50 | Sentinel 执行写回 | Context 文档 + assertion + 提案出现在 DataHub 中 | | 2:50–3:00 | 结束幻灯片 | "Open-source. New DataHub Skill. Repo + examples/. Try it." | ## 锁定版本 (PDF §10.2 "到处都是锁定版本") | 组件 | 版本 | 备注 | |---|---|---| | Next.js | 16.1.1 | App Router, TypeScript | | LangChain | 0.3.x | 通过 `langchain` npm (tool-calling) | | DataHub MCP Server | 0.0.4 | 锁定版本,通过 HTTP 调用 | | DataHub Agent Context Kit | langchain-integration | `include_mutations=True` | | Prisma | 6.11.1 | SQLite client | | LLM | `nvidia/llama-3.3-nemotron-super-49b-v1` | temperature 为 0,parallel tool-calls | | LLM 回退 | `openai/gpt-oss-120b` | 遇到 429/timeout 时切换 | | 许可证 | Apache 2.0 | 在仓库 About 中可见 | ## 附加贡献 1. **`skill/incident-triage/`** — 一个遵循 `datahub-skills` SKILL.md 格式的全新 DataHub Skill。教会任何 agent(Claude Code, Cursor, Codex, Copilot, Gemini)与 Sentinel 在代码中运行的相同的闭环事件分类工作流。可通过 `npx skills add` 安装。PR 目标:`datahub-project/datahub-skills`。 2. **`rfc/closed-loop-metadata-agents.md``** — 通用模式:观察信号 → 接入上下文图 → 基于 lineage + ownership + governance 进行推理 → 在现实世界中采取行动 → 将结构化知识写回 → 等待人类反馈 → 更新图。可推广至事件处理之外(ML 审计、合规、代码生成)。 ## 致谢 (PDF §12.2 — 原创性声明) Block 展示了使用 Goose + DataHub MCP Server 进行的人工驱动事件响应。Sentinel 将其扩展为具有 **write-back loop** 的**自主**响应 —— Block 的现有技术是经过赞助商验证的类别,而不是竞争对手。 ## 路线图 (黑客松后) - **第 1–2 周**:合并 Skill PR;发布 RFC;撰写博客文章。 - **第 1–3 个月**:ML 审计子 agent(移植 MLLineageGuard);第二种事件类型(schema 破坏);批准 UI。 - **第 2 季度**:开放核心企业包(policy DSL、SSO、审批工作流、审计导出)。 ## 威胁模型 (PDF §9.5.5) | 威胁 | 缓解措施 | |---|---| | Agent 采取了破坏性操作 | 沙盒 token;no-merge 策略;guardrail 拒绝 | | Agent 写入错误的 metadata | Ownership/glossary 均为**提案**(由人类批准)。Assertions 是唯一直接写入的操作,并且是可逆的。 | | 密钥泄露 | `.env` 排除在 git 之外;在 CI 中使用 gitleaks;仅使用环境变量密钥 | | 通过 DataHub metadata 进行 Prompt injection | 结构化的 tool-call 输入(绝不执行自由文本执行);由 guardrail 进行过滤 | | 许可证 | Apache 2.0 在仓库根目录可见;示例数据集根据 Resources 选项卡是许可证安全的 | ## 状态 **阶段 0 — 基础与仓库规范** ✅ 完成。 **阶段 1 — DataHub Mock + 种子数据** 下一步进行。 有关持续的构建日志,请参见 `worklog.md`。 ## 许可证 Apache 2.0 — 参见 [`LICENSE`](./LICENSE)。
标签:DataHub, TypeScript, 安全插件, 数据治理, 数据质量, 自动化响应, 自动化攻击