Research: Tracker Publish Resource Routing
Feature: 048-tracker-publish-resource-routing Date: 2026-03-10 Status: Complete — no unknowns required external research
Findings
1. Credential Key Availability
Decision: Use credentials["project_key"] for Jira and credentials["team_id"] for Linear.
Rationale: Both keys are already required by factory.py:build_connector() via _require() calls (lines 81 and 88). Any successfully bound tracker already has these keys in ~/.spec-kitty/credentials. The derivation function does not need to validate connector readiness — it only reads the credential dict that _load_runtime() already resolves.
Alternatives considered:
- Deriving from
TrackerProjectConfig.workspace— rejected becauseworkspaceis the provider workspace name (e.g., Jira site), not the resource identifier (e.g., Jira project key) - Adding a new config field to
.kittify/config.yaml— rejected because the data already exists in credentials and adding config fields increases migration burden
2. Payload Forward Compatibility
Decision: Add external_resource_type and external_resource_id as top-level fields in the snapshot payload alongside existing provider and workspace.
Rationale: The SaaS snapshot endpoint (/api/v1/connectors/trackers/snapshots/) accepts JSON payloads with standard forward-compatible handling — unknown fields are ignored by older SaaS versions. No endpoint version bump needed.
Alternatives considered:
- Nesting under a
routingsub-object — rejected for simplicity; top-level fields match the flat structure ofproviderandworkspace - Adding to the event envelope instead — rejected per spec constraint C-002 (Git event envelope must remain unchanged)
3. Null Semantics
Decision: Both fields are null when routing cannot be derived. The publish still succeeds.
Rationale: This matches the existing pattern where project_uuid and project_slug can be null in the event envelope. The SaaS falls back to its current (provider, workspace) resolution path when routing fields are absent.
Alternatives considered:
- Raising an error when routing keys are missing — rejected because it would break existing bindings that lack the credential key (e.g., legacy credentials without
project_key) - Omitting the fields entirely instead of null — rejected because explicit null signals "resolved but unavailable" per the event envelope convention (Section "Field absence vs null" in
docs/reference/event-envelope.md)