Skip to content

feat(downstream): default firstmate self-changes to local-only on downstream instances - #298

Open
rocco-zhang wants to merge 1 commit into
kunchenguid:mainfrom
rocco-zhang:fm/downstream-guard-w4
Open

feat(downstream): default firstmate self-changes to local-only on downstream instances#298
rocco-zhang wants to merge 1 commit into
kunchenguid:mainfrom
rocco-zhang:fm/downstream-guard-w4

Conversation

@rocco-zhang

Copy link
Copy Markdown

Summary

Stop firstmate instances that run a clone of the shared template from accidentally pushing/PR'ing their own changes back to the upstream template.

A downstream instance has origin pointing at the upstream repo it does not own, so firstmate-on-itself changes (and the tool's own self-ship flow) open PRs against the upstream by accident — the public repo fills with instance PRs that were never meant as contributions.

Approach

Detect downstream-vs-owner from live git/gh identity, and default a downstream instance's own firstmate changes to local-only (no remote, no PR). Contributing upstream stays possible but becomes a deliberate, explicit opt-in (FM_CONTRIBUTE=1).

Changes

  • bin/fm-downstream.sh (new): resolves origin's GitHub owner vs the authenticated gh login. A fork you own → owner; unresolvable identity → downstream (safe default).
  • bin/fm-tangle-lib.sh: fm_is_firstmate_repo — authoritative firstmate-on-itself check via the shared git common dir.
  • bin/fm-project-mode.sh: --firstmate-self resolves to local-only when downstream, unchanged no-mistakes pipeline path when owner/maintainer.
  • bin/fm-spawn.sh / bin/fm-brief.sh: consume the self-change mode; brief DoD becomes local-only-aware for a downstream self-change.
  • bin/fm-pr-check.sh / bin/fm-pr-merge.sh: hard-refuse a firstmate self-change PR when downstream unless FM_CONTRIBUTE=1 (the backstop).
  • AGENTS.md (sections 1, 12): documents the downstream-user model.

Tests

shellcheck clean. New tests/fm-downstream.test.sh (8 cases: owner/downstream/unresolvable detection, origin-URL parsing, mode resolution, brief DoD, both PR-seam refusals + opt-in). Existing fm-brief / fm-pr-merge / fm-tangle-guard / fm-spawn suites pass.

Verified live: a downstream instance detects as downstream, resolves self-changes to local-only, and refuses arming a self-change merge poll without the opt-in.

…nstream instances

A firstmate instance cloned from the shared template has origin pointing at
the upstream repo the user does not own, so firstmate-on-itself ship tasks and
the self-ship flow open PRs against upstream by accident.

- bin/fm-downstream.sh: detect owner vs downstream from live git origin owner
  vs authenticated gh login; unresolvable identity degrades to downstream.
- fm_is_firstmate_repo (fm-tangle-lib.sh): authoritative firstmate-on-itself
  check via shared git common dir.
- fm-project-mode.sh --firstmate-self: downstream -> local-only, owner ->
  no-mistakes; wired into fm-spawn.sh (git identity) and fm-brief.sh flag.
- fm-pr-check.sh / fm-pr-merge.sh: hard-refuse a firstmate self-change PR when
  downstream unless FM_CONTRIBUTE=1 (explicit upstream-contribution opt-in).
- AGENTS.md sections 1 and 12 document the downstream-user model.
This was referenced Jul 24, 2026
This was referenced Jul 28, 2026
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.

1 participant