ln-654-resource-lifecycle-auditor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePaths: File paths (,shared/,references/) are relative to skills repo root. If not found at CWD, locate this SKILL.md directory and go up one level for repo root.../ln-*
路径: 文件路径(、shared/、references/)是相对于技能仓库根目录的。如果在当前工作目录未找到,请定位到本SKILL.md所在目录,然后向上一级即为仓库根目录。../ln-*
Resource Lifecycle Auditor (L3 Worker)
资源生命周期审计器(L3 Worker)
Specialized worker auditing resource acquisition/release patterns, scope mismatches, and connection pool hygiene.
专门用于审计资源获取/释放模式、范围不匹配以及连接池健康状况的Worker。
Purpose & Scope
目标与范围
- Worker in ln-650 coordinator pipeline - invoked by ln-650-persistence-performance-auditor
- Audit resource lifecycle (Priority: HIGH)
- Check session/connection scope mismatch, streaming endpoint resource holding, cleanup patterns, pool config
- Write structured findings to file with severity, location, effort, recommendations
- Calculate compliance score (X/10) for Resource Lifecycle category
- ln-650协调器流水线中的Worker - 由ln-650-persistence-performance-auditor调用
- 审计资源生命周期(优先级:高)
- 检查会话/连接范围不匹配、流式端点资源持有、资源清理模式、连接池配置
- 将结构化检查结果写入文件,包含严重程度、位置、修复工作量及建议
- 计算资源生命周期类别的合规分数(X/10)
Inputs (from Coordinator)
输入(来自协调器)
MANDATORY READ: Load .
shared/references/audit_worker_core_contract.mdReceives with: , , (database type, ORM settings, pool config, session factory), , .
contextStoretech_stackbest_practicesdb_configcodebase_rootoutput_dirDomain-aware: Supports + .
domain_modecurrent_domain必读: 加载。
shared/references/audit_worker_core_contract.md接收包含以下内容的:、、(数据库类型、ORM设置、连接池配置、会话工厂)、、。
contextStoretech_stackbest_practicesdb_configcodebase_rootoutput_dir领域感知: 支持 + 。
domain_modecurrent_domainWorkflow
工作流程
MANDATORY READ: Load for detection methodology.
shared/references/two_layer_detection.md-
Parse context from contextStore
- Extract tech_stack, best_practices, db_config, output_dir
- Determine scan_path
-
Detect DI framework
- FastAPI , Django middleware, Spring
Depends()/@Autowired, Express middleware, Go wire/fx@PersistenceContext
- FastAPI
-
Discover resource infrastructure
- Find session/connection factory patterns (,
sessionmaker,create_engine, pool creation)DataSource - Find DI registration (,
Depends(), providers, middleware mounting)@Inject - Find streaming endpoints (SSE, WebSocket, long-poll, streaming response)
- Map: which endpoints receive which resources via DI
- Find session/connection factory patterns (
-
Scan codebase for violations (6 checks)
- Trace resource injection -> usage -> release across endpoint lifetime
- Analyze streaming endpoints for held resources
- Check error paths for cleanup
-
Collect findings with severity, location, effort, recommendation
-
Calculate score using penalty algorithm
-
Write Report: Build full markdown report in memory per, write to
shared/templates/audit_worker_report_template.mdin single Write call{output_dir}/654-resource-lifecycle.md -
Return Summary: Return minimal summary to coordinator (see Output Format)
必读: 加载以了解检测方法。
shared/references/two_layer_detection.md-
解析contextStore中的上下文
- 提取tech_stack、best_practices、db_config、output_dir
- 确定扫描路径
-
检测DI框架
- FastAPI的、Django中间件、Spring的
Depends()/@Autowired、Express中间件、Go的wire/fx@PersistenceContext
- FastAPI的
-
发现资源基础设施
- 查找会话/连接工厂模式(、
sessionmaker、create_engine、连接池创建)DataSource - 查找DI注册(、
Depends()、提供者、中间件挂载)@Inject - 查找流式端点(SSE、WebSocket、长轮询、流式响应)
- 映射:哪些端点通过DI接收哪些资源
- 查找会话/连接工厂模式(
-
扫描代码库以查找违规问题(6项检查)
- 跟踪资源注入 -> 使用 -> 释放的全端点生命周期
- 分析流式端点的资源持有情况
- 检查错误路径中的资源清理
-
收集包含严重程度、位置、工作量及建议的检查结果
-
使用惩罚算法计算分数
-
生成报告: 根据在内存中构建完整的Markdown报告,通过单次写入操作保存到
shared/templates/audit_worker_report_template.md{output_dir}/654-resource-lifecycle.md -
返回摘要: 向协调器返回极简摘要(参见输出格式)
Audit Rules (Priority: HIGH)
审计规则(优先级:高)
1. Resource Scope Mismatch
1. 资源范围不匹配
What: Resource injected via DI lives for entire request/connection scope but is used for only a fraction of it.
Detection (Python/FastAPI):
- Step 1 - Find endpoints with DB session dependency:
- Grep:
async def\s+\w+\(.*Depends\(get_db\)|Depends\(get_session\)|db:\s*AsyncSession|session:\s*AsyncSession
- Grep:
- Step 2 - Measure session usage span within endpoint body:
- Count lines between first and last usage
session\.|db\.|await.*repo - Count total lines in endpoint function body
- Count lines between first and last
- Step 3 - Flag if (session used in <20% of function body)
usage_lines / total_lines < 0.2- Especially: session used only at function start (auth check, initial load) but function continues with non-DB work
Detection (Node.js/Express):
- Middleware injects or
req.dbat request startreq.knex - Grep: (middleware injection)
app\.use.*pool|app\.use.*knex|app\.use.*prisma - Route handler uses only in first 20% of function body
req.db
Detection (Java/Spring):
- on method with long non-DB processing
@Transactional - injected but used only briefly
EntityManager - Grep: + method body analysis
@Autowired.*EntityManager|@PersistenceContext
Detection (Go):
- or
sql.DBpassed to handler, used once, then long processing*gorm.DB - Grep:
func.*Handler.*\*sql\.DB|func.*Handler.*\*gorm\.DB
Severity:
- CRITICAL: Session scope mismatch in streaming endpoint (SSE, WebSocket) - session held for minutes/hours
- HIGH: Session scope mismatch in endpoint with external API calls (session held during network latency)
- MEDIUM: Session scope mismatch in endpoint with >50 lines of non-DB processing
Recommendation: Extract DB operations into scoped function; acquire session only for the duration needed; use block instead of endpoint-level DI injection.
async with get_session() as session:Effort: M (refactor DI to scoped acquisition)
问题描述: 通过DI注入的资源在整个请求/连接范围内存在,但仅在其中一小部分时间被使用。
检测方式(Python/FastAPI):
- 步骤1 - 查找带有数据库会话依赖的端点:
- 匹配:
async def\s+\w+\(.*Depends\(get_db\)|Depends\(get_session\)|db:\s*AsyncSession|session:\s*AsyncSession
- 匹配:
- 步骤2 - 测量端点函数体内会话的使用跨度:
- 统计首次和最后一次使用之间的代码行数
session\.|db\.|await.*repo - 统计端点函数体的总行数
- 统计首次和最后一次
- 步骤3 - 如果(会话仅在不到20%的函数体中被使用),则标记为违规:
使用行数 / 总行数 < 0.2- 尤其注意:会话仅在函数开头(权限校验、初始加载)使用,但函数后续执行非数据库相关操作
检测方式(Node.js/Express):
- 中间件在请求开始时注入或
req.dbreq.knex - 匹配:(中间件注入)
app\.use.*pool|app\.use.*knex|app\.use.*prisma - 路由处理程序仅在函数体前20%的代码中使用
req.db
检测方式(Java/Spring):
- 带有注解的方法包含长时间非数据库处理
@Transactional - 注入了但仅短暂使用
EntityManager - 匹配:+ 方法体分析
@Autowired.*EntityManager|@PersistenceContext
检测方式(Go):
- 或
sql.DB被传递给处理程序,仅使用一次,之后进行长时间处理*gorm.DB - 匹配:
func.*Handler.*\*sql\.DB|func.*Handler.*\*gorm\.DB
严重程度:
- CRITICAL(严重): 流式端点(SSE、WebSocket)中的会话范围不匹配 - 会话被持有数分钟/数小时
- HIGH(高): 包含外部API调用的端点中的会话范围不匹配 - 会话在网络延迟期间被持有
- MEDIUM(中): 包含超过50行非数据库处理代码的端点中的会话范围不匹配
建议: 将数据库操作提取到作用域函数中;仅在需要的时间段内获取会话;使用代码块替代端点级别的DI注入。
async with get_session() as session:修复工作量: M(重构DI以支持作用域内获取)
2. Streaming Endpoint Resource Holding
2. 流式端点资源持有
What: SSE, WebSocket, or long-poll endpoint holds DB session/connection for stream duration.
Detection (Python/FastAPI):
- Step 1 - Find streaming endpoints:
- Grep:
StreamingResponse|EventSourceResponse|SSE|async def.*websocket|@app\.websocket - Grep: (SSE generator pattern)
yield\s+.*event|yield\s+.*data:|async for.*yield
- Grep:
- Step 2 - Check if streaming function/generator has DB session in scope:
- Session from in endpoint signature -> held for entire stream
Depends() - Session from context manager inside generator -> scoped (OK)
- Session from
- Step 3 - Analyze session usage inside generator:
- If session used once at start (auth/permission check) then stream loops without DB -> scope mismatch
Detection (Node.js):
- Grep:
res\.write\(|res\.flush\(|Server-Sent Events|new WebSocket|ws\.on\( - Check if connection/pool client acquired before stream loop and not released
Detection (Java/Spring):
- Grep:
SseEmitter|WebSocketHandler|StreamingResponseBody - Check if wraps streaming method
@Transactional
Detection (Go):
- Grep:
Flusher|http\.Flusher|websocket\.Conn - Check if or transaction held during flush loop
*sql.DB
Severity:
- CRITICAL: DB session/connection held for entire SSE/WebSocket stream duration (pool exhaustion under load)
- HIGH: DB connection held during long-poll (>30s timeout)
Recommendation: Move auth/permission check BEFORE stream: acquire session, check auth, release session, THEN start streaming. Use separate scoped session for any mid-stream DB access.
Effort: M (restructure endpoint to release session before streaming)
问题描述: SSE、WebSocket或长轮询端点在整个流持续期间持有数据库会话/连接。
检测方式(Python/FastAPI):
- 步骤1 - 查找流式端点:
- 匹配:
StreamingResponse|EventSourceResponse|SSE|async def.*websocket|@app\.websocket - 匹配:(SSE生成器模式)
yield\s+.*event|yield\s+.*data:|async for.*yield
- 匹配:
- 步骤2 - 检查流式函数/生成器的作用域中是否包含数据库会话:
- 端点签名中来自的会话 -> 会在整个流期间被持有
Depends() - 生成器内部上下文管理器中的会话 -> 作用域正确(合规)
- 端点签名中来自
- 步骤3 - 分析生成器内部的会话使用情况:
- 如果会话仅在开始时使用一次(权限校验),之后流循环不涉及数据库 -> 范围不匹配
检测方式(Node.js):
- 匹配:
res\.write\(|res\.flush\(|Server-Sent Events|new WebSocket|ws\.on\( - 检查连接/池客户端是否在流循环前获取且未被释放
检测方式(Java/Spring):
- 匹配:
SseEmitter|WebSocketHandler|StreamingResponseBody - 检查是否包裹了流式方法
@Transactional
检测方式(Go):
- 匹配:
Flusher|http\.Flusher|websocket\.Conn - 检查或事务是否在刷新循环期间被持有
*sql.DB
严重程度:
- CRITICAL(严重): 数据库会话/连接在整个SSE/WebSocket流持续期间被持有(负载下会导致连接池耗尽)
- HIGH(高): 数据库连接在长轮询期间被持有(超时>30秒)
建议: 将权限校验移至流开始前:获取会话,校验权限,释放会话,然后开始流式传输。对于流中间的数据库访问,使用独立的作用域会话。
修复工作量: M(重构端点以在流式传输前释放会话)
3. Missing Resource Cleanup Patterns
3. 缺失资源清理模式
What: Resource acquired without guaranteed cleanup (no try/finally, no context manager, no close()).
Detection (Python):
- Grep: NOT inside
session\s*=\s*Session\(\)|session\s*=\s*sessionmaker|engine\.connect\(\)orwithasync with - Grep: NOT followed by
connection\s*=\s*pool\.acquire\(\)|conn\s*=\s*await.*connect\(\)try:.*finally:.*close\(\) - Pattern: bare without context manager
session = get_session() - Safe patterns to exclude: ,
async with session_factory() as session:with engine.connect() as conn:
Detection (Node.js):
- Grep: without corresponding
pool\.connect\(\)|knex\.client\.acquireConnection|\.getConnection\(\)or.release()in same function.end() - Grep: without
createConnection\(\)in try/finally.destroy()
Detection (Java):
- Grep: without try-with-resources
getConnection\(\)|dataSource\.getConnection\(\) - Pattern: without
Connection conn = ds.getConnection()syntaxtry (Connection conn = ...)
Detection (Go):
- Grep: without
sql\.Open\(|db\.Begin\(\)defer.*Close\(\)|defer.*Rollback\(\) - Pattern: without
tx, err := db.Begin()defer tx.Rollback()
Severity:
- HIGH: Session/connection acquired without cleanup guarantee (leak on exception)
- MEDIUM: File handle or cursor without cleanup in non-critical path
Exception: Session acquired and released before streaming/long-poll begins → skip. NullPool / config documented as serverless design → skip.
pool_sizeRecommendation: Ensure resources are cleaned up on all exit paths (context managers, try-finally, or framework-managed lifecycle).
Effort: S (wrap in context manager or add defer)
问题描述: 获取资源但未保证进行清理(无try/finally、无上下文管理器、无close()调用)。
检测方式(Python):
- 匹配:且不在
session\s*=\s*Session\(\)|session\s*=\s*sessionmaker|engine\.connect\(\)或with代码块内async with - 匹配:且未在后续跟随
connection\s*=\s*pool\.acquire\(\)|conn\s*=\s*await.*connect\(\)try:.*finally:.*close\(\) - 模式:裸未使用上下文管理器
session = get_session() - 可排除的安全模式:、
async with session_factory() as session:with engine.connect() as conn:
检测方式(Node.js):
- 匹配:且在同一函数中无对应的
pool\.connect\(\)|knex\.client\.acquireConnection|\.getConnection\(\)或.release().end() - 匹配:且在try/finally中无
createConnection\(\).destroy()
检测方式(Java):
- 匹配:且未使用try-with-resources
getConnection\(\)|dataSource\.getConnection\(\) - 模式:未使用
Connection conn = ds.getConnection()语法try (Connection conn = ...)
检测方式(Go):
- 匹配:且无
sql\.Open\(|db\.Begin\(\)defer.*Close\(\)|defer.*Rollback\(\) - 模式:无
tx, err := db.Begin()defer tx.Rollback()
严重程度:
- HIGH(高): 获取会话/连接但未保证清理(异常时会导致泄漏)
- MEDIUM(中): 非关键路径中文件句柄或游标未进行清理
例外情况: 会话在流式传输/长轮询开始前获取并释放 → 跳过。NullPool / 配置被记录为无服务器设计 → 跳过。
pool_size建议: 确保在所有退出路径上清理资源(上下文管理器、try-finally或框架管理的生命周期)。
修复工作量: S(包裹在上下文管理器中或添加defer)
4. Connection Pool Configuration Gaps
4. 连接池配置缺陷
What: Missing pool health monitoring, no pre-ping, no recycle, no overflow limits.
Detection (Python/SQLAlchemy):
- Grep for :
create_engine\(|create_async_engine\(- Missing -> stale connections not detected
pool_pre_ping=True - Missing -> connections kept beyond DB server timeout (default: MySQL 8h, PG unlimited)
pool_recycle - Missing -> uses default 5 (may be too small for production)
pool_size - Missing -> unbounded overflow under load
max_overflow - or
pool_size=0in web service -> no pooling (anti-pattern)NullPool
- Missing
- Grep for pool event listeners:
- Missing -> no visibility into connection invalidation
@event.listens_for(engine, "invalidate") - Missing -> no connection checkout monitoring
@event.listens_for(engine, "checkout") - Missing -> no connection return monitoring
@event.listens_for(engine, "checkin")
- Missing
Detection (Node.js):
- Grep for :
createPool\(|new Pool\(- Missing /
minconfigurationmax - Missing or
idleTimeoutMillisreapIntervalMillis - Missing connection validation (,
validateConnection)testOnBorrow
- Missing
Detection (Java/Spring):
- Grep: :
DataSource|HikariConfig|HikariDataSource- Missing
leakDetectionThreshold - Missing (defaults to 10)
maximumPoolSize - Missing or
connectionTestQueryconnectionInitSql
- Missing
Detection (Go):
- Grep: :
sql\.Open\(- Missing
db.SetMaxOpenConns() - Missing
db.SetMaxIdleConns() - Missing
db.SetConnMaxLifetime()
- Missing
Severity:
- HIGH: No pool_pre_ping AND no pool_recycle (stale connections served silently)
- HIGH: No max_overflow limit in web service (unbounded connection creation under load)
- MEDIUM: Missing pool event listeners (no visibility into pool health)
- MEDIUM: Missing leak detection threshold (Java/HikariCP)
- LOW: Pool size at default value (may be adequate for small services)
Context-dependent exceptions:
- NullPool is valid for serverless/Lambda
- pool_size=5 may be fine for low-traffic services
Recommendation: Configure pool_pre_ping=True, pool_recycle < DB server timeout, appropriate pool_size for expected concurrency, add pool event listeners for monitoring.
Effort: S (add config parameters), M (add event listeners/monitoring)
问题描述: 缺失连接池健康监控、无预 ping、无连接回收、无溢出限制。
检测方式(Python/SQLAlchemy):
- 匹配:
create_engine\(|create_async_engine\(- 缺失→ 无法检测 stale 连接
pool_pre_ping=True - 缺失→ 连接保留时间超过数据库服务器超时(默认:MySQL 8小时,PG无限制)
pool_recycle - 缺失→ 使用默认值5(对于生产环境可能过小)
pool_size - 缺失→ 负载下连接溢出无限制
max_overflow - Web服务中使用或
pool_size=0→ 无连接池(反模式)NullPool
- 缺失
- 匹配连接池事件监听器:
- 缺失→ 无法查看连接失效情况
@event.listens_for(engine, "invalidate") - 缺失→ 无连接检出监控
@event.listens_for(engine, "checkout") - 缺失→ 无连接归还监控
@event.listens_for(engine, "checkin")
- 缺失
检测方式(Node.js):
- 匹配:
createPool\(|new Pool\(- 缺失/
min配置max - 缺失或
idleTimeoutMillisreapIntervalMillis - 缺失连接验证(、
validateConnection)testOnBorrow
- 缺失
检测方式(Java/Spring):
- 匹配::
DataSource|HikariConfig|HikariDataSource- 缺失
leakDetectionThreshold - 缺失(默认值为10)
maximumPoolSize - 缺失或
connectionTestQueryconnectionInitSql
- 缺失
检测方式(Go):
- 匹配:
sql\.Open\(- 缺失
db.SetMaxOpenConns() - 缺失
db.SetMaxIdleConns() - 缺失
db.SetConnMaxLifetime()
- 缺失
严重程度:
- HIGH(高): 无pool_pre_ping且无pool_recycle(静默返回stale连接)
- HIGH(高): Web服务中无max_overflow限制(负载下连接创建无限制)
- MEDIUM(中): 缺失连接池事件监听器(无法查看连接池健康状况)
- MEDIUM(中): 缺失泄漏检测阈值(Java/HikariCP)
- LOW(低): 连接池大小为默认值(对于小型服务可能足够)
上下文相关例外情况:
- NullPool在无服务器/Lambda环境中是有效的
- 对于低流量服务,pool_size=5可能足够
建议: 配置pool_pre_ping=True,pool_recycle < 数据库服务器超时,根据预期并发量设置合适的pool_size,添加连接池事件监听器用于监控。
修复工作量: S(添加配置参数),M(添加事件监听器/监控)
5. Unclosed Resources in Error Paths
5. 错误路径中未关闭资源
What: Exception/error handling paths that skip resource cleanup.
Detection (Python):
- Find blocks containing
exceptorraisewithout priorreturn,session.close(), orconn.close()cursor.close() - Pattern: (re-raise without cleanup)
except Exception: logger.error(...); raise - Find generator functions with DB session where GeneratorExit is not handled:
- Grep: without
async def.*yield.*session|def.*yield.*sessiontry:.*finally:.*close\(\)
- Grep:
Detection (Node.js):
- Grep: blocks that
catch\s*\(orthrowwithout releasing connectionreturn - Pattern: without
pool.connect().then(client => { ... }).finally(() => client.release()) - Promise chains without for cleanup
.finally()
Detection (Java):
- Grep: blocks without
catch\s*\(when connection opened infinally { conn.close() }try - Not using try-with-resources for AutoCloseable resources
Detection (Go):
- Grep: before
if err != nil \{.*returnstatement for resource cleanupdefer - Pattern: error check between and
Open()that returns without closingdefer Close()
Severity:
- CRITICAL: Session/connection leak in high-frequency endpoint error path (pool exhaustion)
- HIGH: Resource leak in error path of API handler
- MEDIUM: Resource leak in error path of background task
Recommendation: Use context managers/try-with-resources/defer BEFORE any code that can fail; for generators, add try/finally around yield.
Effort: S (restructure acquisition to before-error-path)
问题描述: 异常/错误处理路径跳过了资源清理步骤。
检测方式(Python):
- 查找包含或
raise但未先调用return、session.close()或conn.close()的cursor.close()块except - 模式:(重新抛出异常但未清理)
except Exception: logger.error(...); raise - 查找带有数据库会话的生成器函数,但未处理GeneratorExit:
- 匹配:且无
async def.*yield.*session|def.*yield.*sessiontry:.*finally:.*close\(\)
- 匹配:
检测方式(Node.js):
- 查找块中
catch\s*\(或throw但未释放连接的情况return - 模式:无
pool.connect().then(client => { ... }).finally(() => client.release()) - Promise链中无用于清理
.finally()
检测方式(Java):
- 查找块中,当连接在
catch\s*\(中打开时无tryfinally { conn.close() } - 未对AutoCloseable资源使用try-with-resources
检测方式(Go):
- 查找出现在资源清理的
if err != nil \{.*return语句之前defer - 模式:在和
Open()之间进行错误检查并返回,未关闭资源defer Close()
严重程度:
- CRITICAL(严重): 高频率端点错误路径中的会话/连接泄漏(连接池耗尽)
- HIGH(高): API处理程序错误路径中的资源泄漏
- MEDIUM(中): 后台任务错误路径中的资源泄漏
建议: 在任何可能失败的代码之前使用上下文管理器/try-with-resources/defer;对于生成器,在yield周围添加try/finally。
修复工作量: S(重构资源获取逻辑,将其移至错误路径之前)
6. Resource Factory vs Injection Anti-pattern
6. 资源工厂模式与注入反模式
What: Using framework DI to inject short-lived resources into long-lived contexts instead of using factory pattern.
Detection (Python/FastAPI):
- Step 1 - Find DI-injected sessions in endpoint signatures:
- Grep:
Depends\(get_db\)|Depends\(get_session\)|Depends\(get_async_session\)
- Grep:
- Step 2 - Classify endpoint lifetime:
- Short-lived: regular REST endpoint (request/response) -> DI injection OK
- Long-lived: SSE (,
StreamingResponse), WebSocket (EventSourceResponse), background task (@app.websocket)BackgroundTasks.add_task
- Step 3 - Flag DI injection in long-lived endpoints:
- Long-lived endpoint should use factory pattern: at point of need
async with session_factory() as session: - NOT at endpoint level
session: AsyncSession = Depends(get_session)
- Long-lived endpoint should use factory pattern:
Detection (Node.js/Express):
- Middleware-injected pool connection () used in WebSocket handler or SSE route
req.db - Should use: at point of need
const conn = await pool.connect(); try { ... } finally { conn.release() }
Detection (Java/Spring):
- in
@Autowired EntityManagerwith SSE endpoint (@Controller)SseEmitter - Should use: programmatic EntityManager creation from EntityManagerFactory
Detection (Go):
- injected at handler construction time but
*sql.DBshould be acquired per-operation*sql.Conn
Severity:
- CRITICAL: DI-injected session in SSE/WebSocket endpoint (session outlives intended scope by orders of magnitude)
- HIGH: DI-injected session passed to background task (task outlives request)
Recommendation: Use factory pattern for long-lived contexts; inject the factory (sessionmaker, pool), not the session/connection itself.
Effort: M (change DI from session to session factory, add scoped acquisition)
问题描述: 使用框架DI将短生命周期资源注入长上下文中,而非使用工厂模式。
检测方式(Python/FastAPI):
- 步骤1 - 查找端点签名中通过DI注入的会话:
- 匹配:
Depends\(get_db\)|Depends\(get_session\)|Depends\(get_async_session\)
- 匹配:
- 步骤2 - 分类端点生命周期:
- 短生命周期:常规REST端点(请求/响应)→ DI注入合规
- 长生命周期:SSE(、
StreamingResponse)、WebSocket(EventSourceResponse)、后台任务(@app.websocket)BackgroundTasks.add_task
- 步骤3 - 标记长生命周期端点中的DI注入:
- 长生命周期端点应使用工厂模式:在需要时使用
async with session_factory() as session: - 不应在端点级别使用
session: AsyncSession = Depends(get_session)
- 长生命周期端点应使用工厂模式:在需要时使用
检测方式(Node.js/Express):
- 中间件注入的连接池连接()被用于WebSocket处理程序或SSE路由
req.db - 正确做法:在需要时使用
const conn = await pool.connect(); try { ... } finally { conn.release() }
检测方式(Java/Spring):
- 在带有SSE端点()的
SseEmitter中使用@Controller@Autowired EntityManager - 正确做法:从EntityManagerFactory以编程方式创建EntityManager
检测方式(Go):
- 在处理程序构造时注入,但应在每次操作时获取
*sql.DB*sql.Conn
严重程度:
- CRITICAL(严重): SSE/WebSocket端点中使用DI注入的会话(会话存在时间远超预期范围)
- HIGH(高): DI注入的会话被传递给后台任务(任务生命周期超过请求)
建议: 对长上下文使用工厂模式;注入工厂(sessionmaker、连接池)而非会话/连接本身。
修复工作量: M(将DI从会话改为会话工厂,添加作用域内获取逻辑)
Scoring Algorithm
评分算法
MANDATORY READ: Load and .
shared/references/audit_worker_core_contract.mdshared/references/audit_scoring.md必读: 加载和。
shared/references/audit_worker_core_contract.mdshared/references/audit_scoring.mdOutput Format
输出格式
MANDATORY READ: Load and .
shared/references/audit_worker_core_contract.mdshared/templates/audit_worker_report_template.mdWrite report to with and checks: resource_scope_mismatch, streaming_resource_holding, missing_cleanup, pool_configuration, error_path_leak, factory_vs_injection.
{output_dir}/654-resource-lifecycle.mdcategory: "Resource Lifecycle"Return summary to coordinator:
Report written: docs/project/.audit/ln-650/{YYYY-MM-DD}/654-resource-lifecycle.md
Score: X.X/10 | Issues: N (C:N H:N M:N L:N)必读: 加载和。
shared/references/audit_worker_core_contract.mdshared/templates/audit_worker_report_template.md将报告写入,标记,并包含以下检查项:resource_scope_mismatch、streaming_resource_holding、missing_cleanup、pool_configuration、error_path_leak、factory_vs_injection。
{output_dir}/654-resource-lifecycle.mdcategory: "Resource Lifecycle"向协调器返回摘要:
Report written: docs/project/.audit/ln-650/{YYYY-MM-DD}/654-resource-lifecycle.md
Score: X.X/10 | Issues: N (C:N H:N M:N L:N)Critical Rules
关键规则
MANDATORY READ: Load .
shared/references/audit_worker_core_contract.md- Do not auto-fix: Report only
- DI-aware: Understand framework dependency injection lifetime scopes (request, singleton, transient)
- Framework detection first: Identify DI framework before checking injection patterns
- Streaming detection first: Find all streaming/long-lived endpoints before scope analysis
- Exclude tests: Do not flag test fixtures, test session setup, mock sessions
- Exclude CLI/scripts: DI scope mismatch is not relevant for single-run scripts
- Effort realism: S = <1h, M = 1-4h, L = >4h
- Pool config is context-dependent: NullPool is valid for serverless/Lambda; pool_size=5 may be fine for low-traffic services
- Safe pattern awareness: Do not flag resources inside ,
async with, try-with-resources,with(already managed)defer
必读: 加载。
shared/references/audit_worker_core_contract.md- 请勿自动修复: 仅生成报告
- DI感知: 理解框架依赖注入的生命周期作用域(请求、单例、瞬时)
- 先检测框架: 在检查注入模式之前先识别DI框架
- 先检测流式端点: 在范围分析之前先查找所有流式/长生命周期端点
- 排除测试代码: 不要标记测试夹具、测试会话设置、模拟会话
- 排除CLI/脚本: DI范围不匹配对单次运行的脚本不适用
- 工作量真实: S = <1小时,M = 1-4小时,L = >4小时
- 连接池配置与上下文相关: NullPool在无服务器/Lambda环境中有效;对于低流量服务,pool_size=5可能足够
- 识别安全模式: 不要标记、
async with、try-with-resources、with内的资源(已被管理)defer
Definition of Done
完成标准
MANDATORY READ: Load .
shared/references/audit_worker_core_contract.md- contextStore parsed successfully (including output_dir, db_config)
- scan_path determined
- DI framework detected (FastAPI Depends, Django middleware, Spring @Autowired, Express middleware, Go wire)
- Streaming endpoints inventoried
- All 6 checks completed:
- resource scope mismatch, streaming resource holding, missing cleanup, pool configuration, error path leak, factory vs injection
- Findings collected with severity, location, effort, recommendation
- Score calculated using penalty algorithm
- Report written to (atomic single Write call)
{output_dir}/654-resource-lifecycle.md - Summary returned to coordinator
必读:
- 成功解析contextStore(包括output_dir、db_config)
- 确定扫描路径
- 检测到DI框架(FastAPI Depends、Django中间件、Spring @Autowired、Express中间件、Go wire)
- 盘点所有流式端点
- 完成全部6项检查:
- 资源范围不匹配、流式资源持有、缺失资源清理、连接池配置、错误路径泄漏、工厂模式与注入反模式
- 收集包含严重程度、位置、工作量及建议的检查结果
- 使用惩罚算法计算分数
- 将报告写入(原子单次写入操作)
{output_dir}/654-resource-lifecycle.md - 向协调器返回摘要
Reference Files
参考文件
- Audit output schema:
shared/references/audit_output_schema.md
Version: 1.0.0
Last Updated: 2026-03-03
- 审计输出 schema:
shared/references/audit_output_schema.md
版本: 1.0.0
最后更新时间: 2026-03-03