Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Determinism Tier 1 follow-up: markdown audit reports embed a wall-clock timestamp

未关闭
#436 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 2 天内回复

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python
领域
cli, testing, tooling

调研方向

Start in packages/darnit/src/darnit/tools/audit.py at format_results_markdown, which currently writes a wall-clock Generated At stamp. Compare the now_provider kwarg on RemediationExecutor (feature 036) and the scrub() helper plus docstring in tests/darnit/fixtures/error_class_baseline/capture_baseline.py. Decide drop vs opt-in vs injectable clock for the stamp, and whether pass_history[].duration_ms is omitted or documented as non-reproducible. Done when two identical-commit markdown reports match byte-for-byte without scrubbing those fields.

由索引模型根据 Issue 内容生成。

描述

module-core

Follow-up to #418 (Determinism Tier 1), which this gap escaped.

Summary

format_results_markdown in
packages/darnit/src/darnit/tools/audit.py embeds a wall-clock stamp
in every report:

**Generated At:** 2026-09-08T15:47:47.180106Z

Consequence: a markdown audit report can never be byte-for-byte
reproducible, even for an identical commit with an identical verdict
set. Two runs one second apart produce different bytes.

A second, smaller instance: pass_history[].duration_ms is
load-dependent. It reads 0 for fast file-existence checks in practice,
but nothing guarantees that.

How it surfaced

Feature 036's SC-002 required capturing a pre-feature output baseline
and diffing post-feature output against it byte-for-byte. Two
consecutive captures of the same commit did not match. Both fields had
to be scrubbed for the baseline to be stable at all -- see the scrub()
helper in tests/darnit/fixtures/error_class_baseline/capture_baseline.py
and its docstring, which documents both as out of scope for 036 and
points here.

#418's survey covered filesystem iteration order, wall-clock injection
into remediation templates, list ordering, and non-atomic writes. It
did not look at the report formatter, which is why this was missed.

Why it matters

Same argument #418 makes: a compliance tool whose report output drifts
run-to-run undermines the "same commit -> same result" premise that
makes an audit trustworthy. Concretely it also:

  • Blocks any golden-file regression test of markdown output. Any future
    feature wanting to prove "my change is output-neutral" has to
    reinvent the same scrubbing.
  • Makes report diffs noisy in review when an operator commits reports
    to a repo (some fleet operators do).

Scope

Decide between:

  1. Drop the field. Simplest. The information is recoverable from
    the attestation timestamp or the file mtime for anyone who needs it.
  2. Make it opt-in via a formatter argument, default off.
  3. Make it injectable -- feature 036 already established this
    pattern for exactly this problem: RemediationExecutor gained a
    now_provider kwarg (defaulting to datetime.now) so tests can
    pin a fixed clock. Applying the same shape to
    format_results_markdown keeps production behavior while making
    the output testable.

Recommend (3) for consistency with the precedent, or (1) if nobody is
actually consuming the field.

Also decide whether duration_ms should be omitted from serialized
pass_history (it is diagnostic, not evidence) or kept and documented
as non-reproducible.

Non-goals

  • Re-auditing the other formatters. JSON and SARIF do not embed
    timestamps at the per-result level; the attestation predicate has its
    own timestamp, which is legitimate and should stay.
  • Any change to what the audit concludes. This is purely about output
    byte-stability.

Constitution alignment

  • II. Conservative-by-Default: reproducible reports are a
    precondition for the report being usable as evidence.

Related

  • #418 (Determinism Tier 1) -- parent; closed by #424 before this gap
    was found.
  • #419 / #420 / #421 -- the rest of the determinism set.
  • Feature 036 (#435) -- surfaced this, and established the
    now_provider injection pattern option (3) would reuse.
主要语言
Python
星标
22
派生
27
平均合并
2 天 18 小时
30 天内合并 PR
51

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

darnitdevorg/darnit 的其他 Issue

查看 darnitdevorg/darnit 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。