Skip to content

Draft spec_commit is parsed but never compared: a draft from another Spec revision is resumed and published #223

Closed

Description

@guijacquemet

This blocker comes from the external review of #221 (ChatGPT batch 30, claim B7). It also implements the owner's decision of 8 November 2026: a draft saved against a different pinned Spec commit is refused at resume, and a fresh draft is derived from the folders.

draft_format.answers_from_bytes() accepts any 40-digit lowercase hex spec_commit (draft_format.py:218-226). run/draft_file._resume() checks only base_sha256 and then applies the stored answers (run/draft_file.py:127-136). publish_draft() then treats those answers, including repeat confirmations and ID choices, as current. A draft written under another Spec revision is therefore published without the user re-confirming anything under the current rules.

Fix:

  • In _resume(), and in save_draft() after the strict round trip, require answers.spec_commit == SPEC_COMMIT.
  • Otherwise raise DraftFileError with a dedicated code such as spec_commit_mismatch. The message tells the user that the published file is untouched and that a fresh draft will be derived from the folders.
  • Never rewrite the stored commit.

Regression test: start from a complete valid draft and change only spec_commit to another valid 40-hex SHA. Then check that:

  • load_draft refuses;
  • publish_draft refuses;
  • morphobricks.toml is unchanged;
  • the draft bytes are byte-identical;
  • no confirmation is carried forward.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions