idx-cli/docs/OWNERSHIP_SYNC.md
hermes 1631058b8c docs: prune stale planning docs and lean out agent guide
- Remove FEATURE_SPEC.md, TODO.md, and docs/AGENT_INTEGRATION.md; their
  core gaps have shipped. Open work moves to a short ROADMAP.md.
- Remove the CLAUDE.md symlink and rewrite AGENTS.md as a quick guide:
  navigation, rules, and the nix flake check gate.
- Merge OWNERSHIP_SELF_HOSTED.md into OWNERSHIP_PUBLISH.md and drop
  private host integration notes.
- ARCHITECTURE: add MSN endpoints, clarify Bing ingest is unsupported.
- OWNERSHIP_SYNC: note source.pdf_url also carries XLSX URLs.
- systemd example: --history 2 so snapshots stay under the 10 MiB
  client cap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 07:39:21 +00:00

78 lines
3 KiB
Markdown

# Ownership Snapshot Sync
`idx ownership sync` installs a maintained SQLite snapshot into the local ownership DB path.
The command is intentionally manifest-driven so the repo can publish snapshots in GitHub releases, object storage, or a local filesystem path without changing the CLI.
Publishing snapshots is a maintainer task; see `docs/OWNERSHIP_PUBLISH.md`.
## Consumer Inputs
The manifest location is resolved in this order:
1. `idx ownership sync --manifest <path-or-url>`
2. `IDX_OWNERSHIP_SNAPSHOT_MANIFEST`
3. `ownership.snapshot_manifest` in `config.toml`
4. built-in published manifest URL:
`https://github.com/0xrsydn/idx-cli/releases/download/ownership-snapshot-current/ownership-snapshot-manifest.json`
The value can be either:
- a local path to a manifest JSON file
- a remote `http://` or `https://` URL
## Manifest Contract
Current schema version: `1`
```json
{
"schema_version": 1,
"generated_at": "2026-03-31T12:00:00Z",
"source": {
"family": "above1",
"listing_page_url": "https://www.idx.co.id/id/berita/pengumuman/",
"query_url": "https://www.idx.co.id/primary/NewsAnnouncement/GetAllAnnouncement?...",
"pdf_url": "https://www.idx.co.id/StaticData/NewsAndAnnouncement/...pdf",
"title": "Pemegang Saham di atas 1% (KSEI)",
"publish_date": "2026-03-10T00:00:00",
"original_filename": "b9b638e5a8_8928aca255.pdf"
},
"snapshot": {
"kind": "sqlite",
"compression": "none",
"version": "2026-02-27",
"download_url": "https://example.com/ownership-snapshot-2026-02-27-<sha256>.sqlite",
"sqlite_sha256": "<64-char hex sha256>",
"size_bytes": 123456,
"release_count": 2,
"latest_as_of_date": "2026-02-27",
"latest_release_sha256": "<latest ownership_releases.sha256>",
"latest_row_count": 7261,
"ticker_count": 955
}
}
```
Semantics:
- `source` is optional provenance metadata describing the IDX/KSEI report used to build the snapshot.
`source.pdf_url` is a legacy field name: since June 2026 it holds the XLSX URL.
- `download_url` points to the SQLite artifact itself. The filename is an
implementation detail: published assets are immutable and content-addressed
(`ownership-snapshot-YYYY-MM-DD-<sha256>.sqlite`), so consumers must always
follow `download_url` and validate it with `sqlite_sha256` and `size_bytes`.
- `sqlite_sha256` and `size_bytes` are validated before install.
- `latest_*` and `release_count` are validated against the downloaded SQLite contents before replacement.
## Replacement Rules
Without `--force`, sync behaves conservatively:
- no local DB: install snapshot
- empty local DB: replace with snapshot
- local latest release older than snapshot: replace with snapshot
- local latest release/date/count matches snapshot: no-op
- local latest release matches but has fewer releases than snapshot: replace to fill missing history
- local DB newer than snapshot: no-op and keep local data
- local DB diverges at the same latest date: no-op and require `--force`
Replacement is staged through a temp file and validated before the local DB is swapped in.