Skip to content

Normal apply does not mark the proposal as applied #35

Closed

Description

@TreeTreeDi

Problem

cmdApply rejects proposals that already have appliedAt, but the normal successful apply path never writes appliedAt or appliedBy back to proposal.json.

As a result, running backpass apply again can reopen the same review surface. Already-written hunks will usually fail later because their exact-find anchors have drifted, but replay prevention is then accidental rather than an explicit state transition.

Bootstrap already stamps its proposal after applying it:

proposal.appliedAt = new Date().toISOString();
proposal.appliedBy = "bootstrap";
config.state.writeProposal(proposal);

Expected behavior

After a non-dry-run normal apply completes without write failures, persist the same state transition with appliedBy: "apply". A subsequent backpass apply should stop at the existing proposal.appliedAt guard.

If any accepted edit fails, leave the proposal unstamped so the user can resolve the drift and retry.

Activity

  1. kunchenguid commented on Aug 24, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate.

    Confirmed on latest main e468608. cmdApply refuses a proposal that already has appliedAt, but only bootstrap writes that stamp. A successful normal apply leaves the proposal reusable, so replay prevention is accidental rather than an explicit state transition.

    VISION aligns. The human gate should not reopen on an already-written proposal. Failure should be loud and named. Labeling ready-for-pr. PR 36 is the existing help. I will not open a competing PR.

  2. kunchenguid commented on Sep 8, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate.

    Stale-restamp on latest main 4e67dcd. cmdApply still refuses a proposal that already has appliedAt, and successful normal apply still never writes that stamp. Bug remains real.

    VISION: human owns the weights / failure is loud and named — align (gate must not reopen after a clean apply). Evidence / model-faith / budget / local-reads / scope — align or N/A (state transition only). Contract-class: restore.

    PR #36 is still the existing help (open; last firstmate note waiting on author for head-bound no-mistakes attestation + GitHub closer for #35). Leaving ready-for-pr. Not opening a competing PR. Not escalating #36 while the author/CI blocker stands.

  3. kunchenguid commented on Sep 22, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate.

    Stale-restamp on latest main 02af5b8. cmdApply still refuses a proposal that already has appliedAt (src/commands/apply.js:52-56), but the successful normal apply path still never writes appliedAt/appliedBy — only bootstrap stamps (src/commands/bootstrap.js:144-146). status.js still prints the review with \backpass apply`hint for any gated proposal with edits, without checkingappliedAt`. Bug remains real and unhelped.

    PR #36 (author TreeTreeDi) was closed as stale on 2026-09-10 without merge; open PRs #128/#129 do not help this. Not opening a competing PR.

    Contract-class: restore — the unconfigured apply path already promises the appliedAt guard (refuse replay) and bootstrap already performs the same consume stamp; normal apply is the broken default path that never completes that promised transition.

    VISION per-rule:

    • Evidence is the only currency — align / N/A (state transition only; no evidence/corroboration change).
    • The human owns the weights — align (gate must not reopen on an already-written proposal).
    • Nothing the model says is taken on faith — align / N/A (no model claims; measured state only).
    • The budget is the constraint — align / N/A (no budget surface change).
    • It reads what you already have and owns nothing — align / N/A (local proposal.json only).
    • Failure is loud and named — align (replay should be an explicit refused state, not accidental anchor drift).
    • Scope — align (does not widen write surface or default scope).

    Leaving ready-for-pr.

  4. kunchenguid commented on Oct 6, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate.

    Stale-restamp on latest main 0268201 (chore release 0.1.32 #198).

    Still real and unhelped on main: cmdApply still refuses a proposal that already has appliedAt (src/commands/apply.js ~line 99), but the successful normal apply path still never writes appliedAt/appliedBy; only bootstrap stamps it (src/commands/bootstrap.js:144-146). The earlier help, PR #36, was closed without merge; none of the open PRs (#150, #151, #154, #163, #175, #179, #183, #201) touch src/commands/apply.js or the apply stamp. Not opening a competing PR.

    Contract-class: restore (the unconfigured apply path already promises the appliedAt replay guard, and bootstrap already performs the same stamp; normal apply is the broken default path).

    VISION per-rule:

    • Evidence is the only currency: aligns / N/A (state transition only).
    • The human owns the weights: aligns (the review gate should not reopen on an already-written proposal).
    • Nothing the model says is taken on faith: aligns / N/A (measured local state, no model claims).
    • The budget is the constraint: N/A (no budget surface change).
    • It reads what you already have and owns nothing: aligns (local proposal.json only).
    • Failure is loud and named: aligns (replay should be an explicit refused state, not accidental anchor drift).
    • Scope: aligns (does not widen write surface or default scope).

    Leaving ready-for-pr.

  5. kunchenguid commented on Oct 20, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate.

    Stale-restamp on latest main c22f2ad (backpass 0.1.37).

    Still real and unhelped on main: cmdApply still refuses a proposal that already has appliedAt (src/commands/apply.js line 99), but the successful normal apply path still never writes appliedAt/appliedBy; only bootstrap stamps it (src/commands/bootstrap.js:144-145). None of the open PRs add that stamp to normal apply (#214 touches apply.js for per-target proposals but doesn't change this). Not opening a competing PR.

    Contract-class: restore (the unconfigured apply path already promises the appliedAt replay guard, and bootstrap already performs the same stamp; normal apply is the broken default path).

    VISION per-rule:

    • Evidence is the only currency: aligns / N/A (state transition only).
    • The human owns the weights: aligns (the review gate should not reopen on an already-written proposal).
    • Nothing the model says is taken on faith: aligns / N/A (measured local state, no model claims).
    • The budget is the constraint: N/A (no budget surface change).
    • It reads what you already have and owns nothing: aligns (local proposal.json only).
    • Failure is loud and named: aligns (replay should be an explicit refused state, not accidental anchor drift).
    • Scope: aligns (does not widen write surface or default scope).

    Leaving ready-for-pr.

  6. kunchenguid commented on Oct 29, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate: fixed by #241 (merged as 0c864ce). A successful non-dry-run apply now stamps appliedAt and appliedBy: "apply", so the existing replay guard refuses a second apply. Closing.

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

    ready-for-prIssue is in scope and ready for a PR

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions