Skip to content

fix(source-control): require the legacy discovered stamp in publish, and test the re-earn exclusion #12450

Description

@kyle-sexton

Problem

The independent security review of #12394's legacy discovery stamp (commit ee07d83, verdict PASS) left two suggestions in plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.mjs:

  1. publish() (~L1000-1004) allows the one-time legacy stamp but doesn't require it. A prior contrary event that stays without discovered, or a new contrary event without one, passes (undefined === undefined); enforcement rests on collect(). The only path through main() is a race: the sidecar is absent or unparsable when main reads the out directory, then reappears before publish() re-reads it. collect then derives a re-earn with since = at. That isn't reachable by anyone who can't write the out directory, and the commit before feat(autonomy): re-promote a demoted cell once its predicate is met again #12394 behaved the same way.
  2. No test covers the event?.event !== "re-earned" clause, i.e. that a prior re-earned event gaining legacyDiscovered(previousAt) is refused.

Fix

  • In --out mode, publish() refuses any non-re-earned event whose discovered is missing or doesn't parse. The daily-loop test's legacy fixture is then written directly, not built through publish().
  • Add assert.throws(() => publish(out, [{...R, discovered: legacyDiscovered}])) over a file holding a re-earn R.

Done when

  • Both changes land with tests, and the existing publisher (82) and end-to-end (36) suites still pass.

Related

Refs #12394, #12434.

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 2, 2026
  2. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Low
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Decision recorded.

    The #12394 stamp is on main (publish-promotion-evidence.mjs:290, :1002 at origin/main), so nothing blocks this fix. The publisher suite is plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.test.mjs (run by publish-promotion-evidence.test.sh); the body does not name the file holding the 36 end-to-end tests, so the builder states it in the PR. Written by the issue-triage session.
    [quote truncated; the full decision is at the link]

    #12450 (comment)

    I understood this as two changes. In --out mode, publish() should refuse any non-re-earned event whose discovered stamp is missing or unparsable. A new test should cover a prior re-earned event gaining the legacy stamp. The recorded decision settles the open questions, so nothing further is being asked.

    Automated triage, applied by the lanes App.

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 2, 2026
  4. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    on Nov 2, 2026
  5. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 2, 2026
  6. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: it carries host-run. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  7. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: admission moved the issue to status: confirmed; its comment says why.

  8. added
    status: needs-decisionAwaiting a human or maintainer judgment call.
    and removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    on Nov 2, 2026
  9. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.

    Intended outcome: In --out mode publish() refuses any non-re-earned event whose discovered stamp is missing or unparsable, and a test shows a prior re-earn gaining legacyDiscovered is refused.

    Related work

    Open questions

    1. The checkout has no discovered or legacyDiscovered anywhere in the babysit-loop skill, and publish() at publish-promotion-evidence.mjs:897 has no stamp logic. Has the #​12394 stamp (commit ee07d83) landed on the base branch, or should this issue wait for it?
      RECOMMENDED: Treat #​12394's stamp change as a prerequisite and hold this issue until it is on the base branch. Basis: plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.mjs:897
    2. The issue cites an existing daily-loop test legacy fixture built through publish(), plus 82 publisher and 36 end-to-end tests. Which files hold those suites? The checkout has none that mention the stamp.
      RECOMMENDED: Name the daily-loop test file and the commands that run the two suites in the issue, so a run can check the counts. Basis: judgment

    Sources read

    • plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.mjs:897: publish(outDir, events, through, now, {rename}) exists, with no discovered or legacyDiscovered handling
    • plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.mjs:540: collect() exists, with no stamp handling
    • plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.test.mjs: test file exists, with no mention of discovered

    To answer, post a comment that starts with this line:

    **Decision recorded.** <answer>
    

    Automated refinement by the lanes App. Answer with a comment whose first line is **Decision recorded.**.

  10. added
    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.
    and removed
    status: needs-decisionAwaiting a human or maintainer judgment call.
    on Nov 3, 2026
  11. kyle-sexton commented on Nov 3, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded.

    The #12394 stamp is on main (publish-promotion-evidence.mjs:290, :1002 at origin/main), so nothing blocks this fix. The publisher suite is plugins/source-control/skills/babysit-loop/scripts/publish-promotion-evidence.test.mjs (run by publish-promotion-evidence.test.sh); the body does not name the file holding the 36 end-to-end tests, so the builder states it in the PR. Written by the issue-triage session.

    • In --out mode, publish() refuses any non-re-earned event whose discovered is missing or doesn't parse. The daily-loop test's legacy fixture is then written directly, not built through publish().
    • Add assert.throws(() => publish(out, [{...R, discovered: legacyDiscovered}])) over a file holding a re-earn R.
    • Both changes land with tests, and the existing publisher (82) and end-to-end (36) suites still pass.
  12. kyle-sexton commented on Nov 3, 2026

    @kyle-sexton
    MemberAuthor

    Lane 3 claims this for the overnight host-run pass.

  13. kyle-sexton commented on Nov 3, 2026

    @kyle-sexton
    MemberAuthor

    Agent choice, not an owner answer. The decision record above was written by the issue-triage session under the owner's standing direction §1 (decide from evidence). The owner did not answer this question; the comment appears under the owner's login only because the session posts with that account.

  14. github-actions commented on Nov 3, 2026

    @github-actions
    Contributor

    The triage sweep dispatched intake triage for this issue (attempt 1 of 2).

  15. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 3, 2026
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

    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.priority: mediumReal value, no hard deadline; normal backlog flow.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    Work status

    confirmed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions