Skip to content

Factory silently assumes and memoizes Linear when issueSource is unset #404

Description

@khaliqgant

Summary

Factory.#issueSource() silently guesses Linear when config.issueSource is unset and /linear/issues happens to be mounted. This is a latent routing defect: the active contract requires Factory to refuse to route when issueSource is absent, not infer a provider from mount availability.

This is not currently firing in production. The deployed factory-cloud config template explicitly sets issueSource: "github", so this probe is bypassed there. This issue is preventive: the first profile shipped without that field can hit it.

Defects

  1. Mount presence is treated as intent. The current code calls ensureSubRoot(ISSUE_ROOT) and resolves linearReady === 'ready' ? 'linear' : 'github'. A mounted /linear/issues therefore silently selects Linear even when the intended issue surface is GitHub.
  2. The guessed result is process-lifetime sticky. #resolvedIssueSource memoizes the first probe. A transient/startup mount outcome pins routing until the Factory process is restarted.
  3. Logging is backwards. Factory logs only when the guess resolves to GitHub (Linear issue source is not connected; using GitHub issues). The more dangerous outcome—silently resolving to Linear—emits no decision log at all.

Contract contradiction

The operating manual says that when the active contract leaves issueSource unset, Factory must refuse to route rather than assume Linear, and explicitly warns that “assuming Linear is exactly the defect this replaced.” The current fallback reintroduces that behavior.

Expected behavior

  • Treat an unset issueSource as a configuration error/refusal to route.
  • Do not infer routing intent from whether a provider subroot happens to mount.
  • If any compatibility fallback is retained, do not memoize a transient probe indefinitely and log every resolved routing decision symmetrically.

Scope

Please fix and test this separately. It is intentionally not being changed in the silent-empty discovery observability PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions