Skip to content

Upstream contributions within the shared package pipeline

Status: proposed implementation, reviewed 2026-09-13 against Praetor commit 76832ee75c8964f2ffeac338a6a3aa9473c23eda. The development MCP probe passed 35 checks with source digest 6aedd54101efe1fbc1e5951dcde413c00a63aac3953cef301ce7286356966d4f. The checkout also contained unrelated work; inspected source hashes and bounded local reproductions were retained privately. This audit did not contact an upstream forge, execute a model, publish anything, or establish end-to-end contribution readiness.

Extend the package development pipeline, whose reuse decisions already include upstream contribution. Use its common policy, evidence relations, stage planner, executor admission and adapter capabilities. A contribution is a path through that pipeline, not another issue database, framework, bot, or per-IDE implementation.

Existing implementation and concrete gaps

Surface Implemented behavior and source Missing contribution contract
Forge transport internal/forge/forge.go:31-58 supplies common issue/PR creation; github.go:455,547,581,666 performs GitHub HTTP creation, bounded issue listing, and issue labels/state updates. Explicit repository and endpoint injection exist. PR requests have no draft field. There is no PR search/read/update/merge-status or fixed-release capability. Authentication checks a nonempty token, not remotely verified permissions. A local draft must not call ordinary PR creation.
Other forges internal/forge/gitea.go:78-103, gitlab.go:76-101, and forge.go:61-74 return explicit unsupported errors for enforcement; Forgejo shares the Gitea driver. Keep unsupported stages blocked. Configured credentials or recognized provider names must not imply working issue/PR support or silently select GitHub.
Existing issue dedupe internal/forge/issues.go:119-165 indexes trimmed titles, then creates or updates. The index ignores returned entries after 1,000; newly created items are not added to the index; duplicate remote titles are ambiguous; title identity is insufficient for a finding. github.go:593-612 stops after 20 pages without marking a full last page incomplete. Listing also removes PRs. These paths cannot establish a complete duplicate search.
Review validation internal/forge/pr.go:37-44,71-80,150-185 verifies receipt contents, optionally binding a pinned key and head SHA; :198-220 derives reviewer candidates from CODEOWNERS. Unpinned receipt consistency is weaker than an authenticated gate. These checks neither review a remote PR nor authorize publication. Upstream contribution rules/templates apply; Praetor-specific checkboxes, bots and receipts must not be imposed on an unrelated upstream.
Project/discussion projections internal/forge/project.go:53-55,90-107 distinguishes local cache items and remote observations. discussions.go:100 transcribes a supplied accepted discussion into a local ADR, once per discussion. Useful projections, not upstream acceptance evidence or a generic contribution lifecycle. An issue being closed, a cached status, or supplied discussion status does not prove a fix merged.
Public dogfood internal/dogfood/public_git.go admits explicit canonical pinned GitHub repositories with bounded, isolated Git operations. public_verify.go:59-91 verifies effective policy, lock/context, baseline, scan and ratchet. This is Praetor governance verification. It does not execute upstream application tests or prove an upstream product bug. Public-repository enrollment does not authorize arbitrary scripts, builds, fork creation or publication.
Local repair internal/repairrun/config.go:18-33, run_execute.go:58-79,99-167, and workspace_patch.go:51-113 retain source-bound reproduction, candidate changes and scoped verification. Reuse isolation, attempt accounting, bounded commands, source hashes and evidence. Current repair supports explicitly allowed Go source and existing tests; workspace_ast.go:21-38 rejects changed declarations/imports/signatures/calls. It is not a general upstream patch or regression-test generator. No upstream promotion is implemented.
Dependency updates internal/bump/types.go:17-24 identifies package/current/target/channel/module; Go and Node scanners and update commands are real. catalog.go contains static version information. No contribution ID, affected source range, accepted upstream commit, released-fix provenance or downstream patch-retirement relation. Catalog values are not live evidence that a fix was released.
Canary and patch outputs internal/bump/canary.go:50-54 marks a dry-run successful and certified; :121-128 writes diagnostic text with a .patch suffix; :133-154 applies a requested update and optional existing patch. Certification without execution is false evidence. The generated file is not an applicable fix. Apply does not consume verified canary/source/patch identity, and a missing named patch can be skipped. Do not reuse these outputs as contribution or retirement admission until corrected.
Changelog/release internal/changelog/render.go:18-107 and journal.go bind recoverable rendering/cleanup to exact hashes. internal/release/release.go:25-55 checks SemVer, cleanliness and gates, then renders. Reuse atomic snapshot and recovery primitives, not a second ad-hoc journal format. Preparing a changelog is not publishing a release, observing upstream acceptance, or verifying an installed downstream fix. Skip options cannot supply required evidence.
Attribution/provenance internal/supplychain/sbom.go:39 builds Go dependency inventory; slsa.go:54-95 constructs a statement from supplied values. Contribution requirements exist in docs/guides/contributing.md. Inventory and unsigned statement construction do not establish license compatibility, rights to contribute, a signed build, or upstream consent. Record exact upstream LICENSE/NOTICE/CONTRIBUTING/CLA/DCO requirements and copied-code origin. Conflicting or missing licensing evidence remains unresolved.
Policy and entry points internal/config/effective_load.go resolves explicit fleet/org/deployment/workstation/repository sources with provenance. Existing CLI bump/reconcile and MCP repair-status adapters call shared modules. Current effective-policy implementation primarily resolves complexity, not the proposed contribution settings. No shared upstream contribution tool exists. Extend one typed policy slice with real consumers; do not expose inert settings or separate CLI/MCP business logic.

Four hermetic observation probes reproduced current failures: 20 full issue pages returned 2,000 issues and nil error; two identical new titles in one batch created two issues; existing issue 1,001 was ignored and created again; an empty-candidate dry-run on a non-repository reported Success=true and CanaryCertified=true. These probes deliberately observe defects; their passing results are not acceptance tests. No external HTTP requests or model calls were made.

One contribution record in the shared evidence graph

Relate the existing Finding/ReuseDecision -> PackageTask -> Change -> Verification objects to one contribution record. Retain separate evidence for upstream identity, publication and downstream maintenance:

finding -> upstream reproduction -> candidate patch -> local reviewed draft -> authorized publication -> upstream acceptance -> released fix -> downstream verification without patch -> patch retirement

The record needs stable IDs and references, not duplicated artifact bodies:

  • Finding ID, originating consumer/replay IDs, classification, affected package coordinate/version and exact source commit. Distinguish Praetor integration defects, upstream application defects, environment/toolchain failures and unsupported coverage.
  • Canonical upstream forge/host/repository identity; exact reproduction base; optional fork identity and proposed head/base. A Git remote name, module-name heuristic or ambient GITHUB_REPOSITORY must not choose the publication target.
  • Search observations with query scope, timestamps, pagination/completeness, matching issue/PR IDs, head/merge commits and uncertainty. Candidate matches are reviewed before linking; similar titles alone do not merge findings.
  • Reproducer, toolchain/command identity, expected failing assertion, before/after source and artifact hashes, actual result counts, omitted gates and coverage. Observed failure is distinct from a source-verified regression.
  • Patch artifact, allowed paths, original license/attribution references, local draft body, review decision, and evidence bundle digest. Exported text is a separately reviewed sanitized projection.
  • Publication authorization bound to the exact target, operation, patch/head and rendered body digest; durable attempt/idempotency identity; remote issue/PR IDs and readback. Token presence, ownership, a policy setting or an agent's choice cannot substitute for explicit external-publication authorization.
  • Upstream merge/release observations and each downstream consumer's patch/bump state. Model upstream resolution (open, duplicate, declined, accepted, released, reverted, unknown) separately from local preparation/execution state. A failed or declined contribution remains useful evidence.

Deduplicate one compatible upstream cause across consumers while retaining each affected version and reproducer. Different causes, incompatible versions or licensing/runtime constraints must remain separate. A changed source pin, patch, target, or required toolchain invalidates dependent verification and publication admission. A content digest proves integrity relative to captured bytes; source authenticity requires its own verified binding.

Configurable policy, with one resolver and explicit capabilities

Extend the package policy's existing owner/org/forge/repository/stage inputs rather than introducing a new config store. Resolve once, preserve source provenance and pass the same immutable digest to planning, execution, CLI, MCP and future IDE/bot adapters.

Setting group Required behavior
Identity Explicit upstream target, optional contributor fork/destination, package coordinate and policy owner. Public examples use example/upstream and example-contributor/upstream; operational settings supply actual bindings. Credentials remain private references.
Stage admission Independently enable read-only discovery, local reproduction, local patch preparation, publication, follow-up and downstream retirement. Governance constraints only tighten; operational destination precedence is documented. Missing explicitly selected config errors; unknown capability blocks its stage.
Native execution Exact source/toolchain pins, admitted commands, filesystem/network scope, time/output/attempt/cost limits, applicable hook adapter and coverage requirements. Keep upstream execution separate from public governance scanning. Use the shared executor and current router admission work; do not add a parallel dispatcher.
Contribution requirements Pinned upstream contributing/license/notice/template references, attribution and DCO/CLA requirements, reviewer policy and report visibility. Check actual declared requirements; do not forge signatures or attest a CLA on another person's behalf.
Publication Allowed operation and target policy, remote draft requirement where selected, sanitized export rules, authorization/readback and retry limits. Publish remains unavailable when a driver cannot satisfy the requested contract.
Maintenance Recheck cadence/budget, expected release channel, downstream consumer bindings and patch retirement conditions. No blanket fleet schedule is activated by adding a contribution record.

Prefer small additive capability interfaces backed by the existing internal/forge transport for contribution search/status and draft publication, rather than making every driver fake all methods. Declare which operations each adapter implements. The application service uses these interfaces and the existing bounded storage/execution primitives; adapters format results only. Preserve existing public signatures and add explicit versioned fields. Corrections to misleading certification or previously accepted incomplete evidence need a documented migration requiring fresh evidence.

Stage contract

  1. Discover and classify. Import retained finding evidence and inspect the selected upstream's current contribution rules. Search both open and closed issues and PRs and relevant merge/release history. Bound requests/results; exhaustion, authentication failure, rate limits or stale results mean partial/unknown, never “no duplicate exists.” Refresh relevant matches before publication. Read-only discovery may stop at a linked existing report, upstream fix, invalid finding or unsupported environment.
  2. Reproduce on exact upstream source. Preserve a clean immutable base and run the upstream's actual documented commands in a disposable admitted environment. Record native failing tests, prerequisites and failure controls; do not replace upstream tests with a Praetor audit. A new reproducer must fail on the unchanged base and avoid the observed failure mechanism on the candidate. Environment failures do not establish an upstream defect. Unavailable native execution leaves a report candidate with an explicit limitation.
  3. Prepare a minimal local change. Reuse the bounded repair/command infrastructure where its current contract fits. Extend through reviewed language adapters when it does not; do not loosen the narrow repair API silently. Keep the patch minimal and avoid unrelated governance adoption. Verify exact-base application, regression tests, relevant upstream gates and source cleanliness. Keep original-corpus/consumer replay separate from scoped patch verification. Reuse a reviewed upstream fix when it already exists and record its attribution.
  4. Build the reviewable draft. Produce a local bundle with problem, minimal reproduction, expected/actual behavior, affected source/version, search matches, patch, verification and omitted gates, attribution, target and rendered issue/PR text. Report-only contributions can omit a fix but cannot claim fix verification. Keep raw transcripts, private settings, cluster guides, workstation paths and credentials out of exports. An LLM may draft text; deterministic validation and review establish the admitted artifact. Local draft creation does not create a remote draft PR.
  5. Publish only the authorized artifact. Present the concrete bundle for explicit approval of external mutation. Recheck target/head/digest and duplicate status immediately before execution. Read back the exact issue/PR identity, draft state and head. Branch/fork creation and push are separate external operations and must be included in the authorization scope. Preserve normal hooks. Persist attempted/confirmed/ambiguous outcomes; after timeout or crash, inspect remote state before retrying so one accepted create cannot become two submissions. Creating an issue and PR is not an atomic transaction; retain partial success. No merge or unsolicited comment is implied.
  6. Observe acceptance and maintain downstream. Read current upstream review/merge status and propose requested changes through the same candidate/review path. Do not equate closed with merged or merged with released. Bind accepted fix to its actual merge/squash/cherry-pick result and released artifact/version, accounting for backports or reverts. A downstream bump is prepared and tested in isolation without the local patch. Remove only the exact unchanged retained patch after that consumer passes the required checks; protect changed files with snapshot comparison and keep rollback/provenance. Partial fleet success retires patches per consumer, not globally.

Smallest implementation slices and acceptance

Slice Deliverable using existing modules Required proof
0 Truthful prerequisites Correct the issue listing/index/batch defects and canary evidence labels in their existing modules. This extends stage 0 of the package plan. Red/green tests for full-page exhaustion, issue 1,001, same-batch duplicates, duplicate existing titles, dry-run certification and diagnostic-only patch output. Partial discovery cannot authorize creation. No disabled lint/security gates.
1 Shared local contribution plan Add the contribution relation/policy slice to the shared package application service; bounded import and local sanitized draft projection through CLI/MCP. The same finding from two consumers produces one contribution with two origins; conflicting causes remain separate. Source/policy/digest tampering, private data export and absent selected config fail. Repeated local preparation is idempotent; no forge mutation/provider dispatch occurs.
2 GitHub read-only observations Add complete-or-explicitly-partial issue/PR/status capabilities to existing forge transport. Hermetic HTTP contract tests for pagination, rate/auth errors, ambiguous matches, renamed repositories, closed-unmerged PRs and stale snapshots. Missing Gitea/GitLab/Forgejo capabilities fail visibly. Then a specifically selected live read-only target proves actual behavior.
3 One native reproduction and patch Prove one admitted Go upstream fixture using existing isolation, command execution and evidence; retain a rejected negative control. Exact base fails the intended assertion, candidate passes, patch applies only to allowed paths, required native gates run, source/toolchain identities and costs are retained. A changed base or test-only false success blocks verification. All adapters expose the same evidence and limits.
4 Authorized remote draft Extend existing GitHub publication with the selected draft contract, target binding, durable attempt journal and readback. No authorization means zero mutations. Changed reviewed digest/target rejects. Lost response after successful create is recovered without duplicate publication. Wrong head/non-draft readback blocks confirmation. Test against a synthetic owned repository only after concrete authorization.
5 Acceptance and patch retirement Bind upstream acceptance/release observation to existing bump candidate and downstream verification records. Closed-unmerged, merged-unreleased, reverted fix, wrong release source, failed consumer and changed patch all retain the patch. Verified fixed release plus clean no-patch consumer checks permit one exact retirement. Resume after partial failure neither duplicates nor drops another consumer's work.

Keep these slices on the existing package pipeline backlog and shared interconnect initiative. Local evidence artifacts remain private; only reviewed source-based plans and sanitized contribution bundles are public. Completion requires real CLI/MCP parity and relevant source-bound execution/readback, normal Lefthook and verification gates, plus explicit published-state evidence for any publication claim. A unit test suite or catalog declaration alone does not establish a working upstreaming loop.