Skip to content

docs: plan env-driven obsidian-headless sync-config (change 0011)#3

Merged
fx merged 3 commits into
mainfrom
docs/sync-config-bootstrap
May 6, 2026
Merged

docs: plan env-driven obsidian-headless sync-config (change 0011)#3
fx merged 3 commits into
mainfrom
docs/sync-config-bootstrap

Conversation

@fx

@fx fx commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Amend the obsidian-sync spec with a new ### Sync configuration bootstrap requirements subsection: env-var → ob sync-config flag mapping, validation rules, retry semantics, and four GIVEN/WHEN/THEN scenarios. Also adds two error-taxonomy rows and notes src/obsidian/syncconfig.ts in the architecture diagram.
  • Retire the prior Constraints line that deferred sync-mode override ("OUT OF SCOPE for v1") — this change supersedes it.
  • New change document 0011 — Sync Config Bootstrap that plans the implementation: OB_SYNC_FILE_TYPES, OB_SYNC_EXCLUDED_FOLDERS, OB_SYNC_MODE, OB_SYNC_CONFLICT_STRATEGY, OB_SYNC_DEVICE_NAME, OB_SYNC_CONFIGS mapped one-to-one to ob sync-config flags, applied per vault between sync-setup and sync --continuous, with fail-fast enum validation and exponential-backoff retry on non-zero exit. Empty string clears, unset preserves.
  • Update docs/index.yml and docs/index.md with the new change row.

Motivation

Production usage revealed the supervisor never invokes ob sync-config, so the upstream defaults (File types: image, audio, pdf, video) are in force. JSON / TXT / CSV files (e.g. voice transcripts under logs/transcripts/) created on the pod were never pushed to the cloud, even after the user enabled "All other file types" on desktop — that toggle updates the desktop client, not the pod's local filter. The only fix today is kubectl exec + manual ob sync-config, lost on pod restart. This change documents the env-driven solution.

Test plan

Documentation-only PR — no code changes, no tests to run.

  • Verify spec renders cleanly on GitHub (anchors, table, scenarios)
  • Verify change-doc anchors link to spec section #sync-configuration-bootstrap
  • Verify Testing Requirements link points to Architecture › Testing & Lint
  • Verify both docs/index.yml and docs/index.md list change 0011 with status draft

Implementation will land in a follow-up PR once the plan is reviewed.

Summary by CodeRabbit

  • Documentation
    • Added comprehensive docs describing an env-var-driven Sync Config Bootstrap to configure sync file types, excluded folders, sync mode, conflict strategy, configs, and device name without pod access.
  • Specs
    • Introduced a bootstrap phase between setup and continuous sync with validation, retry/failure semantics and uniform application across vaults.
  • Changelog
    • Added draft change entry 0011 (sync-config-bootstrap).

Adds the Sync-configuration-bootstrap requirements to the obsidian-sync
spec and a new change document (0011) that plans how OB_SYNC_* env vars
will drive an `ob sync-config` step between sync-setup and continuous
sync. Lifts the prior "Per-vault sync mode override is out of scope"
constraint and updates the docs indexes.
Copilot AI review requested due to automatic review settings May 6, 2026 21:44
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a design and spec integration for a Sync Config Bootstrap: an env-var-driven startup step (between sync-setup and ob sync --continuous) that maps OB_SYNC_* variables to ob sync-config flags, with validation, retry/failure semantics, lifecycle notes, tasks, and open questions.

Changes

Sync Config Bootstrap

Layer / File(s) Summary
Design Specification
docs/changes/0011-sync-config-bootstrap.md
New design doc describing the Sync Config Bootstrap feature: env-var → ob sync-config flag mapping, validation rules (including empty/unset semantics and enum validation), lifecycle ordering, retry/backoff and failure modes, responsibilities (buildSyncConfigArgs, applyVaultSyncConfig), testing requirements, tasks, and open questions.
Spec Integration
docs/specs/obsidian-sync/index.md
Adds "Sync configuration bootstrap" to the obsidian-sync spec, declares a new module reference src/obsidian/syncconfig.ts, extends error taxonomy with SyncConfigTransientError, SyncConfigPermanentError, and SyncCrashLoop, and states OB_SYNC_* values apply identically across all vaults.
Documentation Indexing
docs/index.md, docs/index.yml
Inserts change entry 0011: sync-config-bootstrap (draft) into the docs changelog and docs/index.yml changes list so the design is discoverable.

Sequence Diagram

sequenceDiagram
    participant Supervisor as Supervisor
    participant Startup as Startup
    participant VaultManager as VaultManager
    participant obCLI as obCLI
    Supervisor->>Startup: read OB_SYNC_* env vars
    Startup->>VaultManager: enumerate fresh vaults
    loop per vault
        VaultManager->>Startup: vault ready
        Startup->>obCLI: run `ob sync-config` with built args
        obCLI-->>Startup: success / transient error / permanent error
        alt success
            Startup->>VaultManager: mark vault configured
        else transient error
            Startup->>Startup: retry with backoff
        else permanent error
            Startup->>VaultManager: mark vault failed (prevent sync-start)
        end
    end
    Startup->>Supervisor: proceed to `ob sync --continuous` for configured vaults
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • fx/ob#1: Related obsidian-sync design and modules that this sync-config-bootstrap spec extends and integrates with.

Poem

🐰 I nibble on docs beneath moonlit logs,
Env vars in a row, like tidy little frogs.
I stitch flags to commands and hum a tune,
Bootstrapping sync so vaults wake soon.
Hop, apply, retry—then rest by the moon.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: documenting an environment-driven sync-config bootstrap feature for obsidian-headless, with the change number 0011. It accurately summarizes the primary purpose of the documentation additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/sync-config-bootstrap

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/changes/0011-sync-config-bootstrap.md`:
- Around line 132-140: The doc references two different signatures for
applyVaultSyncConfig; standardize to a single callable signature across the docs
and examples (update both the function declaration and the example call). Pick
one signature (e.g., applyVaultSyncConfig(vault, deps, log, env) or
applyVaultSyncConfig(vault, deps, env)) and update the definition near "1. Pure
validation..." and the usage in the startSupervisor per-vault init loop (the
example after ensureVaultSetup) to match; also ensure related references to
buildSyncConfigArgs and ensureVaultSetup remain consistent with the chosen
signature.

In `@docs/index.yml`:
- Around line 97-103: Update the index metadata for the entry with id "0011" by
adding "0002" to its depends_on list so the change correctly declares it extends
the supervisor lifecycle from 0002; locate the block for id "0011" (name:
sync-config-bootstrap, spec: obsidian-sync) and replace the empty depends_on: []
with a list containing "0002".

In `@docs/specs/obsidian-sync/index.md`:
- Line 228: The changelog row that currently says "Lifts the prior 'Per-vault
sync mode override is out of scope for v1' constraint" contradicts earlier
language that keeps per-vault overrides out of scope (the phrasing "Per-vault
sync mode override is out of scope for v1"); update the changelog entry text
(the 2026-05-06 Add Sync-configuration-bootstrap line) to explicitly state that
the new sync-configuration-bootstrap adds an env-var-driven bootstrap step and
mappings/validation/retry semantics but does not enable per-vault sync mode
overrides for v1, so the wording does not imply that the out-of-scope constraint
has been lifted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2d050390-90e0-4cc0-b0b0-810bdbbec112

📥 Commits

Reviewing files that changed from the base of the PR and between 8bf5a53 and 4e19473.

📒 Files selected for processing (4)
  • docs/changes/0011-sync-config-bootstrap.md
  • docs/index.md
  • docs/index.yml
  • docs/specs/obsidian-sync/index.md

Comment thread docs/changes/0011-sync-config-bootstrap.md
Comment thread docs/index.yml Outdated
Comment thread docs/specs/obsidian-sync/index.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This documentation-only PR updates the Obsidian Sync spec and change-log to plan and specify an env-driven ob sync-config bootstrap step (new Change 0011) so sync settings can be configured via OB_SYNC_* environment variables between sync-setup and sync --continuous.

Changes:

  • Add a new Sync configuration bootstrap requirements section to the Obsidian Sync spec (env-var → flag mapping, validation rules, retry semantics, and scenarios).
  • Introduce Change 0011 — Sync Config Bootstrap as the implementation plan (design + tasks + testing requirements).
  • Register Change 0011 in docs/index.yml and docs/index.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
docs/specs/obsidian-sync/index.md Adds spec requirements + scenarios for env-driven ob sync-config, plus error taxonomy and architecture diagram note.
docs/index.yml Adds Change 0011 entry to the documentation index.
docs/index.md Adds Change 0011 row to the changes table.
docs/changes/0011-sync-config-bootstrap.md New change document describing motivation, requirements, design, tasks, and open questions for env-driven sync-config bootstrap.

Comment thread docs/specs/obsidian-sync/index.md Outdated
Comment thread docs/specs/obsidian-sync/index.md Outdated
Comment thread docs/index.yml Outdated
Comment thread docs/index.md Outdated
Comment thread docs/changes/0011-sync-config-bootstrap.md Outdated
- 0011 change doc: standardize applyVaultSyncConfig signature to
  (vault, deps, log, env) on line 133 to match the call site on line 140
- docs/index.yml: set change 0011 depends_on to ["0002"] (extends the
  supervisor lifecycle introduced in 0002)
- obsidian-sync changelog: clarify that change 0011 replaces the prior
  global sync-config deferral; per-vault overrides remain out of scope

Also includes parallel Copilot-thread fixes already in the working tree
(0011 Depends On line 9, docs/index.md row 27, sync-spec lines 97/110).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/specs/obsidian-sync/index.md`:
- Line 68: Change the unconditional requirement to invoke ob sync-config into a
conditional one: update the sentence referencing the supervisor invoking "ob
sync-config --path <dir>" (after "sync-setup" and before spawning "ob sync
--continuous") so it reads that the supervisor MUST invoke "ob sync-config
--path <dir>" with flags derived from environment variables UNLESS all OB_SYNC_*
environment variables are unset (in which case the supervisor MUST NOT invoke
"ob sync-config"). Also adjust the related rules around "ob sync-config" (the
section covering OB_SYNC_* handling, currently around lines 101-104) to match
this single unambiguous rule so both the "sync-setup" paragraph and the
OB_SYNC_* paragraph state the same conditional behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 77c44270-de9c-4bce-9d16-b4be7a6fb776

📥 Commits

Reviewing files that changed from the base of the PR and between 4e19473 and 744cba7.

📒 Files selected for processing (4)
  • docs/changes/0011-sync-config-bootstrap.md
  • docs/index.md
  • docs/index.yml
  • docs/specs/obsidian-sync/index.md

Comment thread docs/specs/obsidian-sync/index.md Outdated
Resolves CodeRabbit review feedback: the prior wording at line 68 was
unconditional ('MUST invoke') but the rest of the section (and the
'all sync-config vars unset' scenario) requires skipping when every
OB_SYNC_* var is unset. Make line 68 conditional so implementers have
a single unambiguous rule.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
docs/specs/obsidian-sync/index.md (1)

203-204: ⚡ Quick win

Clarify whether SyncConfig error types are part of the public surface.

The Error taxonomy documents SyncConfigTransientError and SyncConfigPermanentError, and snippet 1 shows that the existing code exports similar Setup* error types from src/obsidian/index.ts. However, the "Public surface to the rest of the app" section (lines 151-173) doesn't mention error exports at all.

For consistency and clarity, consider adding a note to the Public surface section specifying whether SyncConfigTransientError and SyncConfigPermanentError should be exported following the established pattern, or whether they're internal-only to the obsidian module.

📝 Suggested clarification

Add after line 169 (before the closing ```):

 interface Supervisor {
   list(): VaultStatus[];
   get(slug: string): VaultStatus | null;
   stop(): Promise<void>;
 }
+
+// Error types (for callers that need to distinguish error causes)
+class SetupPermanentError extends Error { ... }
+class SetupTransientError extends Error { ... }
+class SyncConfigPermanentError extends Error { ... }
+class SyncConfigTransientError extends Error { ... }

Or add a prose note below line 173:

 - `list()` and `get()` MUST be synchronous, non-blocking reads of in-memory state.
 - The supervisor MUST NOT expose raw child handles to other modules.
+- Error types (`SetupPermanentError`, `SetupTransientError`, `SyncConfigPermanentError`, `SyncConfigTransientError`) MUST be exported to allow callers to distinguish error causes.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/specs/obsidian-sync/index.md` around lines 203 - 204, The docs currently
list SyncConfigTransientError and SyncConfigPermanentError in the error taxonomy
but do not state whether they are exported on the obsidian public surface;
update the "Public surface to the rest of the app" section to explicitly state
whether these error types are exported (following the existing pattern of
exporting Setup* errors from src/obsidian/index.ts) or are internal-only.
Specifically, indicate the intended visibility (exported vs internal), and if
exported, add a note listing the exact symbols SyncConfigTransientError and
SyncConfigPermanentError so readers know to import them from the obsidian
module.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@docs/specs/obsidian-sync/index.md`:
- Around line 203-204: The docs currently list SyncConfigTransientError and
SyncConfigPermanentError in the error taxonomy but do not state whether they are
exported on the obsidian public surface; update the "Public surface to the rest
of the app" section to explicitly state whether these error types are exported
(following the existing pattern of exporting Setup* errors from
src/obsidian/index.ts) or are internal-only. Specifically, indicate the intended
visibility (exported vs internal), and if exported, add a note listing the exact
symbols SyncConfigTransientError and SyncConfigPermanentError so readers know to
import them from the obsidian module.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6caa665f-2784-4ded-8efe-ba22badad4ef

📥 Commits

Reviewing files that changed from the base of the PR and between 744cba7 and 4ef817d.

📒 Files selected for processing (1)
  • docs/specs/obsidian-sync/index.md

@fx fx merged commit 43e1e0f into main May 6, 2026
1 check passed
@fx fx deleted the docs/sync-config-bootstrap branch May 6, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants