Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contributing

Contributions are welcome. Small, isolated fixes can go straight to a pull
request. For anything that changes behavior, architecture, state, file writes,
or a public interface, open an issue first so we can agree on the approach.

## Before you start

Use the owner table in [the architecture guide](docs/architecture.md) before
changing code, then read the relevant flow, invariant, and change-impact
sections.

For a nontrivial change, post a short plan on the issue before implementation:

- What behavior should change, and what are the acceptance criteria?
- Which module owns the decision, and which direct callers are involved?
- Can the change affect SQLite state, provider checkpoints, configuration,
  reports, or local files?
- What happens after interruption, retry, partial failure, or config drift?
- Which safety contract or focused scenario slice applies, and which tests
  will prove the behavior?
- Which user-facing surfaces need matching changes?

Discuss the approach before deleting production code or tests, changing a
public CLI/API contract, or adding a dependency or broad configuration option.

## Engineering expectations

### Work in the owning layer

1. Find the relevant area in [the architecture guide](docs/architecture.md).
2. Search for the exact symbol, command, flag, SQL name, config key, or error.
3. Read the owner module and its direct callers before editing.
4. Trace shared types, traits, schema, serialization, tokens, and paths through
   all consumers.
5. Update the architecture guide when ownership or a documented flow changes.

Keep policy in its owner. For example, path formatting must not decide sync
policy, and the download pipeline must not own CloudKit response parsing.

### Protect user data

Follow the architecture guide's
[data-safety invariants](docs/architecture.md#data-safety-invariants). Media and
metadata must never be lost, corrupted, truncated, overwritten, or silently
discarded. Local rewrites stay opt-in, provider behavior stays in its adapter,
and trust-boundary validation and data-loss guards stay intact.

Changes involving file writes, SQLite state, provider identity, or checkpoints
must cover interruption, retry, partial completion, and stale configuration.

### Keep the change narrow

- Prefer the smallest complete fix in the fewest owning files.
- Reuse or delete before adding a helper or abstraction.
- Prefer the standard library, then native platform/SQLite features, then
  existing dependencies.
- Add a dependency only when it is clearly better than the existing choices.
- Avoid one-implementation traits, factories, builders, speculative
  compatibility, and configuration without a current requirement.
- Prefer direct, readable code over clever or generalized code.

## Workflow

1. Fork the repository and create a branch from `main`.
2. Run `cargo check` before code work.
3. Make the smallest complete change in the owning module.
4. Add focused tests for behavior changes.
5. Run the changed command or user flow when practical.
6. Review the diff for unrelated changes, unnecessary complexity, missed
   consumers, and incomplete docs.
7. Run focused tests for the changed behavior, formatting, and lint checks.
   Hosted PR CI owns the complete offline suites, platform checks, and routed
   stress checks. Do not run the complete local gate merely to repeat it in CI.
   Use `just gate` when diagnosing a failure or working without hosted CI.
   The [recipes](justfile) define the commands. See the
   [test entry points](tests/README.md#running) for focused checks.
   Live-provider and real host-service tests belong on an explicitly approved,
   isolated local fixture when the change needs them, not on every PR.
   Read [CI qualification](docs/ci.md) for routing and release prerequisites.
   Tool versions are pinned in [.github/workflows/checks.yml](.github/workflows/checks.yml).

8. Open a pull request against `main`.

All changes go through pull requests. Do not commit directly to `main`.

## Tests

- Every behavior change needs a focused test.
- Prefer a test that exercises the real production call graph.
- Put unit tests near the owning module and cross-module behavior in `tests/`.
- Assert concrete outcomes and edge cases, not only that a call succeeds.
- For CLI changes, run the changed command and check Docker, systemd, Homebrew,
  and documentation surfaces where applicable.
- Do not dismiss a failing test as unrelated without investigating it.

Apply the [state-transition proof requirements](tests/README.md#state-transition-proof)
when the change affects durable behavior. That section defines applicability,
the required stages, and the evidence to report.

Some tests (`tests/sync.rs`, `tests/state_auth.rs`, and
`tests/import_existing_live.rs`) contact the live iCloud API and need real
credentials. They are `#[ignore]` by default. See
[tests/README.md](tests/README.md) for setup, then run:

```sh
just test live
```

Most changes do not need live tests. CI runs the offline suite on every pull
request.

## Pull requests and review

Describe the end state, not the sequence of edits. Include:

- The behavior changed and why
- The related issue, using `Fixes #123` or `Closes #123` when appropriate
- Affected safety-contract IDs or focused scenario slices, when applicable
- Exact commands and scenarios tested
- Data, state, filesystem, compatibility, or migration risks
- Tradeoffs or follow-up work that remains

Reviews prioritize:

- Correctness and user-data safety
- Ownership and layer boundaries
- Interruption, retry, and partial-state behavior
- Provider checkpoint, state, serialization, and config consistency
- Focused evidence through tests
- Unnecessary scope, abstraction, or configuration
- User-visible behavior and migration effects

## Rust style

- Rust 2024 edition with the minimum Rust version declared in `Cargo.toml`
- `cargo fmt` and `cargo clippy` must pass cleanly
- Warnings are errors in CI
- Use typed errors and `?`; do not use `unwrap` in production code
- Prefer borrowing to cloning and enums to boolean mode arguments
- Use newtypes for IDs, paths, units, tokens, and other easy-to-mix values
- Keep internal APIs `pub(crate)` unless a public surface or test-harness
  precedent requires `pub`

## Wiki documentation

The wiki is a separate repository. Follow the [wiki maintenance checklist](docs/wiki-maintenance.md) for manual version-scoped command/configuration checks, canonical-guide ownership, URL compatibility and publication evidence. Repository tooling changes do not publish wiki content.

## Logs and config snippets

Code must not log Apple IDs, passwords, session cookies, bearer tokens, or
unredacted provider identifiers. Preserve `SecretString`, password redaction,
and other credential boundaries when changing logging or error paths.

Before posting logs or configuration, redact Apple IDs, passwords, session
cookies, bearer tokens, webhook URLs, and local paths you do not want public.
Keep enough surrounding text for the failure to remain readable.

## License

By contributing, you agree that your contributions are licensed under the
[MIT License](LICENSE).