MCP HubMCP Hub
스킬 목록으로 돌아가기

implement-audit-trail

pjt222
업데이트됨 Yesterday
17
2
17
GitHub에서 보기
디자인aidesign

정보

이 스킬은 규제 환경에서 R 프로젝트를 위한 감사 추적 기능을 구현하는 데 도움을 주며, 21 CFR Part 11 준수에 중점을 둡니다. 이벤트 로깅, 데이터 출처 추적, 전자 서명, 데이터 무결성 검사를 다룹니다. 규제 제출을 위해 변조 방지 분석 기록을 생성하거나 R 분석에서 누가 언제 무엇을 했는지 추적해야 할 때 사용하세요.

빠른 설치

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에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서


name: implement-audit-trail description: > Implementar funcionalidad de registro de auditoría para proyectos R en entornos regulados. Cubre registro de eventos, seguimiento de procedencia, firmas electrónicas, verificaciones de integridad de datos y cumplimiento de 21 CFR Parte 11. Usar cuando un análisis R requiere cumplimiento de registros electrónicos (21 CFR Parte 11), cuando se necesita rastrear quién hizo qué y cuándo en un análisis, al implementar seguimiento de procedencia de datos, o al crear registros de análisis a prueba de manipulaciones para envíos regulatorios. locale: es source_locale: en source_commit: 6f65f316 translator: claude-sonnet-4-6 translation_date: 2026-03-16 license: MIT allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: compliance complexity: advanced language: R tags: audit-trail, logging, provenance, 21-cfr-part-11, data-integrity

Implementar Registro de Auditoría

Añadir capacidades de registro de auditoría a proyectos R para el cumplimiento normativo.

Cuándo Usar

  • Un análisis R requiere cumplimiento de registros electrónicos (21 CFR Parte 11)
  • Se necesita rastrear quién hizo qué, cuándo y por qué en un análisis
  • Al implementar seguimiento de procedencia de datos
  • Al crear registros de análisis a prueba de manipulaciones

Entradas

  • Requerido: Proyecto R con scripts de procesamiento de datos o análisis
  • Requerido: Requisitos regulatorios (qué elementos del registro de auditoría son obligatorios)
  • Opcional: Infraestructura de registro existente
  • Opcional: Requisitos de firma electrónica

Procedimiento

Paso 1: Configurar el Registro Estructurado

Crear 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)
}

Esperado: R/audit_log.R creado con las funciones init_audit_log() y log_audit_event(). Al llamar a init_audit_log() se crea el directorio audit_logs/ y un archivo JSONL con marca de tiempo. Cada entrada del registro es una línea JSON única con los campos timestamp, event, analyst y session_id.

En caso de fallo: Si jsonlite::toJSON() falla, asegurarse de que el paquete jsonlite esté instalado. Si no se puede crear el directorio del registro, verificar los permisos del sistema de archivos. Si las marcas de tiempo carecen de zona horaria, verificar que %z sea compatible con la plataforma.

Paso 2: Añadir Verificaciones de Integridad de Datos

#' 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
}

Esperado: hash_data() devuelve una cadena hash SHA-256 y registra un evento DATA_HASH. verify_data_integrity() compara los datos actuales con un hash almacenado y registra un evento DATA_VERIFY con estado PASS o FAIL.

En caso de fallo: Si digest::digest() no se encuentra, instalar el paquete digest. Si los hashes no coinciden para datos idénticos, verificar que el orden de columnas y los tipos de datos sean consistentes entre el hash y la verificación.

Paso 3: Rastrear Transformaciones de Datos

#' 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
}

Esperado: audited_transform() envuelve cualquier función de transformación, registrando las dimensiones y el hash de entrada, las dimensiones y el hash de salida, y la descripción de la transformación como un evento DATA_TRANSFORM.

En caso de fallo: Si la función de transformación genera un error, el evento de auditoría no se registra. Envolver la transformación en tryCatch() para registrar tanto los éxitos como los fallos. Asegurarse de que la función de transformación acepte y devuelva un data frame.

Paso 4: Registrar el Entorno de la Sesión

#' 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
  ))
}

Esperado: Un evento SESSION_INFO registrado con versión de R, plataforma, configuración regional, paquetes adjuntos con versiones y el hash del archivo de bloqueo renv (si aplica).

En caso de fallo: Si sessionInfo() devuelve información incompleta de paquetes, asegurarse de que todos los paquetes estén cargados mediante library() antes de llamar a log_session_info(). El hash del archivo de bloqueo renv será NA si el proyecto no usa renv.

Paso 5: Implementar en Scripts de Análisis

# 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()

Esperado: Los scripts de análisis inicializan el registro de auditoría al inicio, registran cada importación de datos, transformación y paso de análisis, y registran la información de la sesión al final. El archivo de registro JSONL captura la cadena completa de procedencia.

En caso de fallo: Si falta init_audit_log(), asegurarse de que R/audit_log.R esté incluido o que el paquete esté cargado. Si faltan eventos en el registro, verificar que log_audit_event() se llame después de cada operación significativa.

Paso 6: Control de Cambios Basado en Git

Complementar el registro de auditoría a nivel de aplicación con 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."

Esperado: Los commits de git están firmados (GPG) y usan mensajes descriptivos que hacen referencia a los IDs de control de cambios. La combinación del registro de auditoría JSONL a nivel de aplicación y el historial de git proporciona un registro completo de control de cambios.

En caso de fallo: Si la firma GPG falla, configurar la clave de firma con git config --global user.signingkey KEY_ID. Si la clave no está configurada, seguir gpg --gen-key para crear una.

Validación

  • El registro de auditoría captura todos los eventos requeridos (inicio, acceso a datos, transformaciones, análisis, exportación)
  • Las marcas de tiempo usan el formato ISO 8601 con zona horaria
  • Los hashes de datos permiten la verificación de integridad
  • La información de la sesión está registrada
  • Los registros son solo de adición (sin eliminación ni modificación)
  • La identidad del analista se captura para cada sesión
  • El formato del registro es legible por máquina (JSONL)

Errores Comunes

  • Registrar demasiado: Enfocarse en los eventos regulados. No registrar cada asignación de variable.
  • Registros mutables: Los registros de auditoría deben ser solo de adición. Usar JSONL (un objeto JSON por línea).
  • Marcas de tiempo faltantes: Cada evento necesita una marca de tiempo con zona horaria.
  • Sin contexto de sesión: Cada entrada del registro debe hacer referencia a la sesión para su correlación.
  • Olvidar inicializar: Los scripts deben llamar a init_audit_log() antes de cualquier análisis.

Habilidades Relacionadas

  • setup-gxp-r-project — estructura del proyecto para entornos validados
  • write-validation-documentation — protocolos e informes de validación
  • validate-statistical-output — metodología de verificación de salidas
  • configure-git-repository — control de versiones como parte del control de cambios

GitHub 저장소

pjt222/agent-almanac
경로: i18n/es/skills/implement-audit-trail
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

executing-plans

디자인

executing-plans 스킬은 검토 체크포인트가 포함된 통제된 배치로 실행할 완전한 구현 계획이 있을 때 사용합니다. 이 스킬은 계획을 불러와 비판적으로 검토한 후, 소규모 배치(기본값 3개 작업)로 작업을 실행하면서 각 배치 사이에 진행 상황을 아키텍트 검토를 위해 보고합니다. 이를 통해 내재된 품질 관리 체크포인트를 갖춘 체계적인 구현이 보장됩니다.

스킬 보기

requesting-code-review

디자인

이 스킬은 코드 변경 사항을 요구 사항에 따라 분석하기 위해 코드 리뷰어 하위 에이전트를 호출합니다. 작업 완료 후, 주요 기능 구현 후, 또는 메인 브랜치에 병합하기 전에 사용해야 합니다. 이 리뷰는 현재 구현체와 원래 계획을 비교하여 문제를 조기에 발견하는 데 도움이 됩니다.

스킬 보기

connect-mcp-server

디자인

이 스킬은 개발자들이 HTTP, stdio 또는 SSE 전송 방식을 통해 MCP 서버를 Claude Code에 연결하는 포괄적인 가이드를 제공합니다. GitHub, Notion 및 사용자 정의 API와 같은 외부 서비스를 통합하기 위한 설치, 구성, 인증 및 보안을 다룹니다. MCP 통합 설정, 외부 도구 구성 또는 Claude의 모델 컨텍스트 프로토콜 작업 시 활용하세요.

스킬 보기

web-cli-teleport

디자인

이 스킬은 작업 분석을 기반으로 개발자가 Claude Code 웹 인터페이스와 CLI 인터페이스 중 선택할 수 있도록 돕고, 두 환경 간 원활한 세션 텔레포트를 가능하게 합니다. 웹, CLI 또는 모바일 환경 전환 시 세션 상태와 컨텍스트를 관리하여 워크플로를 최적화합니다. 다양한 단계에서 서로 다른 도구가 필요한 복잡한 프로젝트에 사용하세요.

스킬 보기