返回技能列表

implement-audit-trail

pjt222
更新于 Yesterday
4 次查看
17
2
17
在 GitHub 上查看
aidesigndata

关于

This skill implements audit trail functionality for R projects in regulated environments, focusing on 21 CFR Part 11 compliance. It provides logging, provenance tracking, electronic signatures, and data integrity checks to create tamper-evident analysis logs. Use it when you need to track "who did what and when" for regulatory submissions or data integrity requirements.

快速安装

Claude Code

推荐
主要方式
npx skills add pjt222/agent-almanac -a claude-code
插件命令备选方式
/plugin add https://github.com/pjt222/agent-almanac
Git 克隆备选方式
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/implement-audit-trail

在 Claude Code 中复制并粘贴此命令以安装该技能

技能文档

實稽核軌跡

為管制環境之 R 專案加稽核軌跡能力。

適用時機

  • R 分析需電子記錄合規(21 CFR Part 11)
  • 須追蹤分析中誰何時何事何故
  • 實資料出處追蹤
  • 建防篡改之分析日誌

輸入

  • 必要:含資料處理或分析腳本之 R 專案
  • 必要:監管要求(何稽核軌跡要素為強制)
  • 選擇性:現有日誌基礎設施
  • 選擇性:電子簽章要求

步驟

步驟一:設結構化日誌

R/audit_log.R

#' Initialize audit log for a session
#'
#' @param log_dir Directory for audit log files
#' @param analyst Name of the analyst
#' @return Path to the created log file
init_audit_log <- function(log_dir = "audit_logs", analyst = Sys.info()["user"]) {
  dir.create(log_dir, showWarnings = FALSE, recursive = TRUE)

  log_file <- file.path(log_dir, sprintf(
    "audit_%s_%s.jsonl",
    format(Sys.time(), "%Y%m%d_%H%M%S"),
    analyst
  ))

  entry <- list(
    timestamp = format(Sys.time(), "%Y-%m-%dT%H:%M:%S%z"),
    event = "SESSION_START",
    analyst = analyst,
    r_version = R.version.string,
    platform = .Platform$OS.type,
    working_directory = getwd(),
    session_id = paste0(Sys.getpid(), "-", format(Sys.time(), "%Y%m%d%H%M%S"))
  )

  write(jsonlite::toJSON(entry, auto_unbox = TRUE), log_file, append = TRUE)
  options(audit_log_file = log_file, audit_session_id = entry$session_id)

  log_file
}

#' Log an audit event
#'
#' @param event Event type (DATA_IMPORT, TRANSFORM, ANALYSIS, EXPORT, etc.)
#' @param description Human-readable description
#' @param details Named list of additional details
log_audit_event <- function(event, description, details = list()) {
  log_file <- getOption("audit_log_file")
  if (is.null(log_file)) stop("Audit log not initialized. Call init_audit_log() first.")

  entry <- list(
    timestamp = format(Sys.time(), "%Y-%m-%dT%H:%M:%S%z"),
    event = event,
    description = description,
    session_id = getOption("audit_session_id"),
    details = details
  )

  write(jsonlite::toJSON(entry, auto_unbox = TRUE), log_file, append = TRUE)
}

預期: R/audit_log.R 已建,含 init_audit_log()log_audit_event() 函數。呼 init_audit_log()audit_logs/ 目錄與時間戳 JSONL 檔。每日誌條目為單一 JSON 行含 timestampeventanalystsession_id 欄。

失敗時:jsonlite::toJSON() 失敗,確 jsonlite 套件已裝。若日誌目錄不能建,核檔案系統權限。若時間戳缺時區,驗 %z 於平台支援。

步驟二:加資料完整性檢查

#' Compute and log data hash for integrity verification
#'
#' @param data Data frame to hash
#' @param label Descriptive label for the dataset
#' @return SHA-256 hash string
hash_data <- function(data, label = "dataset") {
  hash_value <- digest::digest(data, algo = "sha256")

  log_audit_event("DATA_HASH", sprintf("Hash computed for %s", label), list(
    hash_algorithm = "sha256",
    hash_value = hash_value,
    nrow = nrow(data),
    ncol = ncol(data),
    columns = names(data)
  ))

  hash_value
}

#' Verify data integrity against a recorded hash
#'
#' @param data Data frame to verify
#' @param expected_hash Previously recorded hash
#' @return Logical indicating whether data matches
verify_data_integrity <- function(data, expected_hash) {
  current_hash <- digest::digest(data, algo = "sha256")
  match <- identical(current_hash, expected_hash)

  log_audit_event("DATA_VERIFY",
    sprintf("Data integrity check: %s", ifelse(match, "PASS", "FAIL")),
    list(expected = expected_hash, actual = current_hash))

  if (!match) warning("Data integrity check FAILED")
  match
}

預期: hash_data() 返 SHA-256 雜湊字串並記 DATA_HASH 事件。verify_data_integrity() 較當前資料於儲存雜湊並以 PASS 或 FAIL 狀態記 DATA_VERIFY 事件。

失敗時:digest::digest() 未見,裝 digest 套件。若同一資料雜湊不配,核雜湊與驗證間欄順與資料型別一致。

步驟三:追資料轉換

#' Wrap a data transformation with audit logging
#'
#' @param data Input data frame
#' @param transform_fn Function to apply
#' @param description Description of the transformation
#' @return Transformed data frame
audited_transform <- function(data, transform_fn, description) {
  input_hash <- digest::digest(data, algo = "sha256")
  input_dim <- dim(data)

  result <- transform_fn(data)

  output_hash <- digest::digest(result, algo = "sha256")
  output_dim <- dim(result)

  log_audit_event("DATA_TRANSFORM", description, list(
    input_hash = input_hash,
    input_rows = input_dim[1],
    input_cols = input_dim[2],
    output_hash = output_hash,
    output_rows = output_dim[1],
    output_cols = output_dim[2]
  ))

  result
}

預期: audited_transform() 包任何轉換函數,記輸入尺寸與雜湊、輸出尺寸與雜湊、轉換描述為 DATA_TRANSFORM 事件。

失敗時: 若轉換函數錯,稽核事件不記。以 tryCatch() 包轉換以記成與敗。確轉換函數接受並返資料框。

步驟四:記會話環境

#' Log complete session information for reproducibility
log_session_info <- function() {
  si <- sessionInfo()

  log_audit_event("SESSION_INFO", "Complete session environment recorded", list(
    r_version = si$R.version$version.string,
    platform = si$platform,
    locale = Sys.getlocale(),
    base_packages = si$basePkgs,
    attached_packages = sapply(si$otherPkgs, function(p) paste(p$Package, p$Version)),
    renv_lockfile_hash = if (file.exists("renv.lock")) {
      digest::digest(file = "renv.lock", algo = "sha256")
    } else NA
  ))
}

預期:SESSION_INFO 事件含 R 版本、平台、區域、附載套件含版本與 renv 鎖檔雜湊(若適用)。

失敗時:sessionInfo() 返不全套件資訊,確所有套件經 library()log_session_info() 前載。若專案不用 renv,renv 鎖檔雜湊為 NA

步驟五:於分析腳本實行

# 01_analysis.R
library(jsonlite)
library(digest)

# Start audit trail
log_file <- init_audit_log(analyst = "Philipp Thoss")

# Import data with audit
raw_data <- read.csv("data/raw/study_data.csv")
raw_hash <- hash_data(raw_data, "raw study data")

# Transform with audit
clean_data <- audited_transform(raw_data, function(d) {
  d |>
    dplyr::filter(!is.na(primary_endpoint)) |>
    dplyr::mutate(bmi = weight / (height/100)^2)
}, "Remove missing endpoints, calculate BMI")

# Run analysis
log_audit_event("ANALYSIS_START", "Primary efficacy analysis")
model <- lm(primary_endpoint ~ treatment + age + sex, data = clean_data)
log_audit_event("ANALYSIS_COMPLETE", "Primary efficacy analysis", list(
  model_class = class(model),
  formula = deparse(formula(model)),
  n_observations = nobs(model)
))

# Log session
log_session_info()

預期: 分析腳本始時初始化稽核日誌,記每資料匯入、轉換、分析步驟,末記會話資訊。JSONL 日誌檔捕完整出處鏈。

失敗時:init_audit_log() 缺,確 R/audit_log.R 已來源或套件已載。若事件自日誌缺,驗 log_audit_event() 於每重要操作後呼之。

步驟六:基於 git 之變更控制

以 git 補應用層稽核軌跡:

# Use signed commits for non-repudiation
git config commit.gpgsign true

# Descriptive commit messages referencing change control
git commit -m "CHG-042: Add BMI calculation to data processing

Per change request CHG-042, approved by [Name] on [Date].
Validation impact assessment: Low risk - additional derived variable."

預期: Git 提交已簽章(GPG)並用描述訊息參考變更控制 ID。應用層 JSONL 稽核軌跡與 git 歷史之合構成完整變更控制記錄。

失敗時: 若 GPG 簽章失敗,以 git config --global user.signingkey KEY_ID 配簽章金鑰。若金鑰未設,循 gpg --gen-key 以建之。

驗證

  • 稽核日誌捕所有所需事件(始、資料取、轉換、分析、輸出)
  • 時間戳用 ISO 8601 格式附時區
  • 資料雜湊允許完整性驗證
  • 會話資訊已記
  • 日誌為只附加(無刪或改)
  • 每會話捕分析師身分
  • 日誌格式可機讀(JSONL)

常見陷阱

  • 記過多:專注於管制事件。勿記每變數賦值。
  • 可變日誌:稽核日誌須只附加。用 JSONL(一行一 JSON 物件)。
  • 缺時間戳:每事件需附時區之時間戳。
  • 無會話情境:每日誌條目應參考會話以供關聯。
  • 忘初始化:腳本須於任何分析前呼 init_audit_log()

相關技能

  • setup-gxp-r-project - 驗證環境之專案結構
  • write-validation-documentation - 驗證協定與報告
  • validate-statistical-output - 輸出驗證法
  • configure-git-repository - 版本控制為變更控制之一部

GitHub 仓库

pjt222/agent-almanac
路径: i18n/wenyan-lite/skills/implement-audit-trail
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

相关推荐技能

content-collections

Content Collections 是一个 TypeScript 优先的构建工具,可将本地 Markdown/MDX 文件转换为类型安全的数据集合。它专为构建博客、文档站和内容密集型 Vite+React 应用而设计,提供基于 Zod 的自动模式验证。该工具涵盖从 Vite 插件配置、MDX 编译到生产环境部署的完整工作流。

查看技能

polymarket

这个Claude Skill为开发者提供完整的Polymarket预测市场开发支持,涵盖API调用、交易执行和市场数据分析。关键特性包括实时WebSocket数据流,可监控实时交易、订单和市场动态。开发者可用它构建预测市场应用、实施交易策略并集成实时市场预测功能。

查看技能

creating-opencode-plugins

该Skill帮助开发者创建OpenCode插件,用于接入命令、文件、LSP等25+种事件。它提供了插件结构、事件API规范和JavaScript/TypeScript实现模式,适合需要拦截操作、扩展功能或自定义事件处理的场景。开发者可通过它快速构建响应式模块来增强OpenCode AI助手的能力。

查看技能

sglang

SGLang是一个专为LLM设计的高性能推理框架,特别适用于需要结构化输出的场景。它通过RadixAttention前缀缓存技术,在处理JSON、正则表达式、工具调用等具有重复前缀的复杂工作流时,能实现极速生成。如果你正在构建智能体或多轮对话系统,并追求远超vLLM的推理性能,SGLang是理想选择。

查看技能