Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Story: Existing Caproni project works unmodified

Story ID: STORY-004 Status: Revision 1 Created: 2026-10-13

Statement

As a developer with an existing Caproni project, I want xianyun to read my current config, environment variables, and on-disk state unchanged, so that I can switch tools without rewriting my project or losing my trusted CA and registry cache.

Trigger

The developer runs any xianyun command in a directory that has caproni.yaml (and possibly caproni.local.yaml, caproni-project.yaml, and ~/.local/share/caproni).

Acceptance Criteria

Scenario: Legacy config filenames load

Given a directory with only "caproni.yaml" and "caproni.local.yaml"
When the developer runs "xianyun config validate"
Then the exit code MUST be 0
And values from "caproni.local.yaml" MUST be merged over "caproni.yaml"

Scenario: An invalid legacy config is reported against the schema

Given a directory with only "caproni.yaml" that sets "cluster.driver: nonsense"
When the developer runs "xianyun config validate"
Then the exit code MUST be non-zero
And the message MUST name "/cluster/driver"
And no cluster MUST be started

Scenario: Legacy variables and environment aliases still work

Given a config value "${CAPRONI_CLUSTER_NAME}" and CAPRONI_NO_CACHE set
When the developer runs "xianyun config print"
Then the value MUST equal the "XIANYUN_CLUSTER_NAME" value
And the cache MUST be disabled as if XIANYUN_NO_CACHE were set

Scenario: Legacy state is reused, not duplicated

Given a CA under "~/.local/share/caproni" and none under "~/.local/share/xianyun"
When the developer runs "xianyun ca inspect"
Then the output MUST show the existing CA
And no new CA MUST be generated

EARS Constraints

  • When both a primary and a legacy file exist in one directory, the system shall use the primary. (Covered by FR-001.2’s scenario rather than here.)
  • The system shall name the in-cluster ClusterIssuer and Secret xianyun-ca and shall not create caproni-ca objects.
  • If --no-cache or XIANYUN_NO_CACHE is set, then the system shall disable remote-fragment caching. (Not met: the flag is read but unused, GAP-005.)
  • When a legacy trust-store entry exists, the system shall remove it on ca untrust.

Autonomy Limits

Not applicable; the actor is a human.

Security Mapping

ConcernAddressed By
Tampering (legacy file shadowing a primary one)Second scenario fixes precedence
Information disclosure (legacy backup file).caproni.bak is still written 0644; SR-010 (not yet met)

Standards Mapping

  • SLSA Level: N/A
  • SSDF Practices: N/A
  • SCVS Controls: N/A

Dependencies

Notes

  • The invalid-config scenario was measured on 2026-10-13: xianyun config validate against a caproni.yaml with driver: nonsense exited 1 with /cluster/driver: "nonsense" is not one of [...]. That run also shows a legacy caproni.yaml is found and read. The valid-config scenario needs a cluster.network block.
  • The first and third scenarios are covered by unit tests in xianyun-core; none has been exercised against an on-disk legacy state in a VM test.
  • Documentation gap: user docs still say caproni-ca and ~/.local/share/caproni, and examples/own-infrastructure.yaml passes --default-issuer-name=caproni-ca. A user following those against xianyun references an issuer that doesn’t exist. This is the most likely way the “unmodified” promise breaks in practice.
  • The data-directory scenario is split in the code: k3d.rs and colima.rs hard-code .local/share/caproni, so some state may be created in the old location even for new profiles.