Skip to content

fix(email): guard specification.html against generator drift#2082

Merged
itomek merged 1 commit into
mainfrom
autofix/issue-2080
Jul 15, 2026
Merged

fix(email): guard specification.html against generator drift#2082
itomek merged 1 commit into
mainfrom
autofix/issue-2080

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

The email agent's specification.html is a committed, integrator-facing doc that is a pure render of spec_html.py — but nothing stopped the two from drifting apart. If a hand-edited section had ever landed in the file without a matching generator change, the next render_endpoint_spec_html() regeneration would silently drop it and no test would notice. This adds the same drift guard openapi.email.json already has: a python -m gaia_agent_email.spec_html regenerate/--check CLI plus a test that fails loudly the moment the file and its generator diverge. (The pair is byte-identical today, so this is purely protective — no doc content changes.)

Closes #2080

Test plan

  • python -m pytest tests/test_spec_html_artifact.py -x passes
  • python util/lint.py --all passes
  • python -m gaia_agent_email.spec_html --check exits 0 on the synced pair
  • Append a stray line to specification.html--check exits 1 and the drift test fails; revert → both pass again
🔍 Technical details

Root cause: specification.html had no regeneration path and no drift test, unlike its sibling artifact openapi.email.json (guarded by export_openapi.check_artifact() + test_committed_openapi_artifact_is_up_to_date). Regeneration was therefore unsafe — a file-only edit would survive until the next regen, then vanish silently.

Changes:

  • gaia_agent_email/spec_html.py — add ARTIFACT_PATH (the committed specification.html next to openapi.email.json), write_artifact(), check_artifact() (reads the file, compares to a fresh render_endpoint_spec_html(), never rewrites), and a main() with --check/--output so python -m gaia_agent_email.spec_html regenerates and --check diffs. Exported in __all__; added if __name__ == "__main__". Directly mirrors export_openapi.py.
  • tests/test_spec_html_artifact.py — new drift test mirroring the openapi one: asserts the committed file matches the generator, that a diverged/missing file is reported stale, and that write_artifact round-trips through check_artifact.

Acceptance criteria: the generator reproduces the committed file byte-identically (verified — check_artifact() returns True today); the new test fails loudly on divergence (verified by appending a line → --check exits 1); any generator-emitted section (incl. the referenced #1892/#1889 content, which is present in both today) now survives regeneration by construction, since the file is the generator output and the guard forbids file-only edits.

Verified: pytest tests/test_spec_html_artifact.py → 4 passed; tests/test_rest_contract.py → all pass except the pre-existing test_agent_version_matches_package_metadata (needs the wheel pip installed for dist metadata — an env artifact, not this change); black/isort/flake8 pass.

Add write_artifact/check_artifact + a python -m gaia_agent_email.spec_html
regenerate/--check CLI, and a drift test mirroring the openapi.email.json
guard, so specification.html can never silently diverge from spec_html.py
and drop hand-maintained sections on a regeneration.

Closes #2080
@itomek itomek added this pull request to the merge queue Jul 15, 2026
Merged via the queue into main with commit 1fe33f0 Jul 15, 2026
7 checks passed
@itomek itomek deleted the autofix/issue-2080 branch July 15, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(email): specification.html has drifted from its generator — regeneration would drop hand-edited sections

1 participant