Bitspark constellation
proposed source ↗

ADR 0015 — cross-repo issue orchestration: native cross-repo sub-issues supersede the prose Part of convention

  • Status: proposed
  • Date: 2026-06-09
  • Relates: 0001 (the membership test), 0005 §4 (propagation), 0008 (release-on-merge), 0011 (the dashboard), 0014 (the process this tracks)
  • Tracking: atlas#453 / atlas#455 (the unified-process rollout epic)
  • Normative spec: process/SPEC.md §7, and the governance/TRACKING.md manifest grammar (build work under atlas#454)

Cross-repo work is tracked by prose. A substrate change that requires coordinated edits in N repos is, today, an atlas issue whose body says constellation: … with same-repo children linked by Part of #N text — or nothing at all. GitHub now supports native sub-issues that cross repositories within one organization, with an automatic roll-up; the whole family is one org. The structured graph exists and is unused; the prose mirror is the rot.

Context

Within a repo, the mature members already use native sub-issues (a type:epic/epic parent with real child links and a sub_issues_summary roll-up). Across repos, there is no structured link at all: coordination is Part of #N prose, repo#N references, and a human keeping a checklist current. constellation-the-probe has zero issues because all its tracking already lives informally in atlas. There is no shared cycle calendar — design and atlas each run "cycles" and "waves" with divergent label syntax (wave-1 vs wave:1).

Two facts make this tractable now:

  1. GitHub native sub-issues cross repositories within one organization — same-org only (the whole family is under Bitspark), ≤100 children per parent, ≤8 nesting levels, and the actor needs ≥triage on each child's repo. The capability is proven inside atlas (e.g. #65); the cross-repo dimension has never been used.
  2. atlas is already the one checkout that can re-derive the whole-family model offline (registry.json + every atlas.jsonconstellation.json) — so it is the one place a cross-repo link graph can be validated, not just asserted.

The membership test (0001) decides where a tracking artifact lives: fleet-wide coordination with no single-repo owner ⇒ atlas.

Decision

1. Fleet epics live in atlas; the membership test decides each issue

Scenario Parent lives Children live
A change touching ≥2 members (substrate, contract, a fleet sweep) atlas epic one native cross-repo child per affected member repo
A bug entirely inside one repo's lane that repo same-repo native sub-issues
A two-repo contract one repo clearly owns owner repo + a Blocks edge n/a

A dedicated tracker repo (a second coordination convention competing with atlas) and constellation-the-probe (the umbrella working dir / integration probe, not a registry member) are both rejected as homes.

2. Native sub-issues are the source of truth

Parent→child, same repo or across repos, is a native sub-issue link — the atlas epic parents a child filed in the member repo. GitHub's sub_issues_summary {total, completed, percent_completed} is the roll-up; no hand-maintained checklist. The prose Part of Bitspark/atlas#N line is retained only as a courtesy human-readable mirror, never as the authority. This supersedes the prose Part of #N convention for cross-cutting work.

3. The relationship vocabulary

Structured (authoritative, machine-reconciled): native sub-issue links (within- and cross-repo). Prose edges, only for what GitHub has no native link for, always fully-qualified Bitspark/<repo>#N:

Edge Syntax Meaning
containment mirror Part of Bitspark/atlas#N courtesy mirror; the native link is authoritative
close-on-merge Closes #N (same-repo only) cross-repo Closes is unsupported — use Resolves Bitspark/<repo>#N
blocking Blocks Bitspark/<repo>#N this must land first
blocked-by Blocked by Bitspark/<repo>#N inverse
dependency Depends on Bitspark/<repo>#N softer than Blocks
relation Related to Bitspark/<repo>#N symmetric context

A bare <repo>#N in a cross-repo edge is a lint error. Bidirectionality is not a hand-maintained mandate: the native link already gives parent/child both directions; Blocks/Depends on are declared once (in the track manifest) and the reverse is rendered in the dashboard, never required as reciprocal prose on the other issue.

4. The constellation-epic / track-manifest pattern

A fleet epic carries type:epic + rollout and one fenced YAML manifest block — the single source atlas track check reconciles against the live native graph:

<!-- atlas:track -->
epic: Bitspark/atlas#NNN
cycle: 2026.07
children:
  - { repo: ontos, issue: 12, prefix: "ontos:", blocks: [] }
  - { repo: logos, issue: 88, prefix: "logos:", blocks: [ontos#12] }
<!-- /atlas:track -->

atlas track check asserts: every declared child is a real native sub-issue; no undeclared children (excepting autonomous-actor issues, §7); each child repo is a ratified member of constellation.json (§6); titles carry the declared prefix; cross-repo refs are fully-qualified. It folds into atlas doctor as the non-blocking track-fresh leg; the hard form atlas track check --strict runs only in atlas's own CI — maintenance, never a member's required gate. The manifest grammar lives in governance/TRACKING.md; the epic.yml template references it rather than embedding it, so the tracking schema and the template-vendoring axis stay decoupled.

5. Honest token + lifecycle scoping

  • atlas track sync --write is an author-run-local capability, not a CI capability. Reaching into member repos to create issues and add sub-issue links needs issues:write (≥triage) on each child repo — strictly larger than the receivers' repository_dispatch scope. It runs under a maintainer's own credential, never a workflow secret. The fleet cron may file tracking issues via its own held credential, but routine epic decomposition is a steward action.
  • GitHub does not auto-close a parent when its sub-issues close. The automatic invariant is the roll-up percentage; epic closure is a deliberate step (atlas track sync --close-complete once the summary hits 100%, or a maintainer).

6. Membership for children: any ratified member, not only substance

A cross-repo child may be filed in any ratified (non-draft) member of constellation.json, of any layersubstance, downstream, or infrastructure. This corrects a conflation: the substrate fan-out subscriber set is substance-and-downstream members with a substrate caller, but the issue-tracking child set is simply "is a member." A downstream member (the schema-sanctioned layer that consumes the family — e.g. a realizer like arche-runner once ratified) is a first-class tracking target. A repo absent from registry.json (constellation-the-probe; an un-ratified arche-runner) cannot be a child until a steward adds it — which is why onboarding such a repo is gated on a membership PR.

7. Autonomous actors are scoped out of the "no undeclared children" rule

Repos with autonomous routines that file their own issues (arche's cloud routines) mark them with a filed-by: provenance (or a bot login); atlas track check excludes those from manifest reconciliation. They remain subject to the label and process gates like any issue.

8. Unified cycles and the issue body template

atlas owns one cycle calendar (governance/cycles.json); members map their own milestone objects to a cycle by id (no forced shared milestone), and children carry the canonical wave:N label. The unified issue body — ## Problem / ## Scope / ## Acceptance / ## Grade (canonical labels, not prose) / ## Provenance (filed-by:, parent:, relationships:) — is specified in process/SPEC.md §7 and seeded by the vendored task.yml/epic.yml forms.

Consequences

  • Cross-repo status is a query, not a stale checklistatlas track list --cycle renders the live sub_issues_summary roll-up; the dashboard (0011) gains a tracking view.
  • The prose Part of #N convention retires for cross-cutting work, becoming a courtesy mirror of an authoritative link.
  • A genuine constraint surfaces honestly: cross-repo issue creation needs a broad credential, so it is a steward-local action — the tooling does not pretend CI auto-creates cross-repo issues.
  • The membership boundary becomes load-bearing for tracking — you cannot file a child in a repo the family hasn't ratified, which is the right gate.

Alternatives considered

  • Keep prose Part of #N + a tracking doc. Rejected: a hand-maintained mirror of a graph GitHub now maintains natively — the rot, with extra steps.
  • A GitHub Project (v2) board. Rejected as the source of truth: Projects are a view, not a checked artifact in a repo's CI; nothing offline reconciles a board against the topology, and the family deliberately uses no Projects today. (A Project may later render the same native links read-only.)
  • A dedicated tracker repo. Rejected: a second coordination home competing with atlas's topology authority; atlas is already the only checkout that can validate the link graph.
  • Cross-repo via the substrate fan-out only (no issue links). Rejected: the fan-out converges pins; it does not express "this human work item in repo A blocks that one in repo B," which is what coordinated multi-repo changes need.

The work that realizes this ADR

atlas track check|sync|list, governance/cycles.json, governance/TRACKING.md, and the epic.yml manifest reference are built under atlas#454; the first real cross-repo sub-issue tree is the rollout's own atlas#455 epic (children filed in each ratified member). See process/SPEC.md.

The Bitspark constellation — how the systems are built and relate.

GitHub