From 5a22f1885c5722f20db80d283fb53961218b7d12 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 05:59:19 -0400 Subject: [PATCH 01/19] chore(7): add backup and restore helper scripts for SQLite data folder --- scripts/backup.sh | 45 ++++++++++++++++++++++++++++++++++++++++ scripts/restore.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 scripts/backup.sh create mode 100644 scripts/restore.sh diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100644 index 0000000..4f7f905 --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Simple Sync backup script +# Usage: ./scripts/backup.sh [--stop] [path-to-db] +# If --stop is provided, the script will stop the docker-compose service before copying and restart it afterwards. + +STOP=false +DB_PATH="./data/simple-sync.db" + +if [ "${1:-}" = "--stop" ]; then + STOP=true + shift +fi + +if [ "$#" -ge 1 ]; then + DB_PATH="$1" +fi + +BACKUP_DIR="./backups" +mkdir -p "$BACKUP_DIR" + +if [ ! -f "$DB_PATH" ]; then + echo "Error: database file not found at $DB_PATH" + exit 1 +fi + +TIMESTAMP=$(date +%Y%m%d%H%M%S) +BACKUP_FILE="$BACKUP_DIR/simple-sync-$TIMESTAMP.db" + +if [ "$STOP" = true ]; then + echo "Stopping simple-sync service..." + docker compose stop simple-sync || true +fi + +echo "Copying $DB_PATH -> $BACKUP_FILE" +cp -- "$DB_PATH" "$BACKUP_FILE" + +if [ "$STOP" = true ]; then + echo "Starting simple-sync service..." + docker compose start simple-sync || true +fi + +echo "Backup complete: $BACKUP_FILE" +exit 0 diff --git a/scripts/restore.sh b/scripts/restore.sh new file mode 100644 index 0000000..8ed2bc3 --- /dev/null +++ b/scripts/restore.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Simple Sync restore script +# Usage: ./scripts/restore.sh [--stop] +# Restores the given backup file into ./data/simple-sync.db. If --stop is provided, the service will be stopped before restore and started after. + +if [ "$#" -lt 1 ]; then + echo "Usage: $0 [--stop]" + exit 2 +fi + +BACKUP_FILE="$1" +shift + +STOP=false +if [ "${1:-}" = "--stop" ]; then + STOP=true +fi + +DB_DIR="./data" +DB_PATH="$DB_DIR/simple-sync.db" + +if [ ! -f "$BACKUP_FILE" ]; then + echo "Error: backup file not found: $BACKUP_FILE" + exit 1 +fi + +mkdir -p "$DB_DIR" + +if [ "$STOP" = true ]; then + echo "Stopping simple-sync service..." + docker compose stop simple-sync || true +fi + +# Safety: move existing DB aside +if [ -f "$DB_PATH" ]; then + OLD_TS=$(date +%Y%m%d%H%M%S) + mv -- "$DB_PATH" "$DB_DIR/simple-sync.db.bak.$OLD_TS" + echo "Moved existing DB to $DB_DIR/simple-sync.db.bak.$OLD_TS" +fi + +cp -- "$BACKUP_FILE" "$DB_PATH" + +if [ "$STOP" = true ]; then + echo "Starting simple-sync service..." + docker compose start simple-sync || true +fi + +echo "Restore complete: $DB_PATH" +exit 0 From 473651ce2d4d4820140d322208bbbeb39305e3f0 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 05:59:37 -0400 Subject: [PATCH 02/19] chore(7): document explicit local data bind and named-volume alternative in docker-compose --- docker-compose.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index dc573db..017118d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,9 @@ services: environment: - PORT=8080 volumes: - - ./data:/app/data + - ./data:/app/data # explicit local bind for persistent DB file (recommended for development) + # Alternative: use a named volume managed by Docker + # - simple-sync-data:/app/data restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "-s", "http://localhost:8080/api/v1/health"] From 0423675d3c55ce3b53ecffb2fff94149449163fa Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 06:00:03 -0400 Subject: [PATCH 03/19] docs(7): document SQLite storage and Docker notes for future agents in AGENTS.md --- AGENTS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 6df0445..b7343c2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,15 @@ Simple-sync is a lightweight REST API built in Go that provides event storage an ### GitHub Data Access +- **Storage & Docker notes (for future agents):** + - The project uses SQLite for persistent storage; production/dev processes expect a local file under `./data` by default (`./data/simple-sync.db`). + - Docker Compose is configured to bind-mount `./data` into the container (`./data:/app/data`) so the DB file is stored on the host. This is the recommended setup for development and simple deployments because it makes backups and inspection straightforward. + - If you need a Docker-managed volume, a named volume `simple-sync-data` exists in `docker-compose.yml` (commented). Using a named volume is fine for environments where host access is not required, but it makes manual backups/restores less obvious. + - Building the Go binary with `github.com/mattn/go-sqlite3` requires a system C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1` during build. CI workflows already install `libsqlite3-dev` where needed. + - For backups, there are helper scripts in `./scripts/backup.sh` and `./scripts/restore.sh` that copy the DB file from `./data` to `./backups` and restore it safely; future agents should prefer these scripts for simple backup/restore workflows. + +### Project Knowledge + - **ALWAYS use GitHub CLI for GitHub data** - NEVER use webfetch for issues, PRs, or other GitHub information - **Issue information**: Use `gh issue view ` - **PR information**: Use `gh pr view ` From efe03832a6033e9fa337f82a592592c883a3ef61 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 06:00:22 -0400 Subject: [PATCH 04/19] docs(7): add Docker Compose persistent data notes and backup/restore usage to README --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 729605c..7aed697 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,27 @@ services: - simple-sync ``` +### Persistent Data (Docker Compose) +The Docker Compose configuration mounts a local `./data` directory into the container (`./data:/app/data`) by default. This is the recommended setup for development and simple deployments because it keeps the SQLite database file on the host, making backups and inspection straightforward. + +If you prefer Docker-managed storage, a named volume `simple-sync-data` is declared in `docker-compose.yml`; you can switch to it by uncommenting the named volume line and removing the `./data` bind mount. + +Backup and restore helper scripts are provided in `./scripts`: +- `./scripts/backup.sh [--stop] [path-to-db]` — copy the DB file to `./backups/` (use `--stop` to stop the container during backup) +- `./scripts/restore.sh [--stop]` — restore a backup into `./data/simple-sync.db` (moves the existing DB aside first) + +Example (take a backup and then start): + +```bash +# create a backup (stop service during the copy) +./scripts/backup.sh --stop +# start services +docker compose up -d +``` + +Developer note: the app uses `github.com/mattn/go-sqlite3` which requires `libsqlite3-dev` and `CGO_ENABLED=1` when building locally or in CI. + + ## Development ### Building From f9984eb668331cab4a3bd70f38452c2c5802b8c3 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 06:00:49 -0400 Subject: [PATCH 05/19] docs(7): add data persistence and backup/restore guide --- docs/data-persistence.mdx | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 docs/data-persistence.mdx diff --git a/docs/data-persistence.mdx b/docs/data-persistence.mdx new file mode 100644 index 0000000..d87d97c --- /dev/null +++ b/docs/data-persistence.mdx @@ -0,0 +1,37 @@ +--- +title: Data Persistence +--- + +## Data Persistence and Backups + +This project uses SQLite for persistent storage. By default the service stores its database file in `./data/simple-sync.db` when you run via Docker Compose. + +### Running with Docker Compose + +The repository ships a `docker-compose.yml` that bind-mounts `./data` into the container (`./data:/app/data`). This keeps the DB file on the host so you can inspect, back up, or move it easily. + +### Backups + +Use the supplied helper scripts: + +- `./scripts/backup.sh [--stop] [path-to-db]` — copies the DB file to `./backups/` with a timestamped filename. Use `--stop` to stop the container during backup for safety. +- `./scripts/restore.sh [--stop]` — restores a backup into `./data/simple-sync.db`. The existing DB (if any) will be moved aside before restore. + +Example workflow: + +```bash +# Stop, backup, and start using the scripts +./scripts/backup.sh --stop +docker compose up -d +``` + +### Security Considerations + +- The database file contains sensitive data. Store backups securely and limit filesystem access. +- For production, consider encrypting the filesystem or using SQLCipher (see issue #17). +- Ensure regular backups and test restores periodically. + +### Developer notes + +- Building the binary with `github.com/mattn/go-sqlite3` requires a C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1`. + From e7c5692e3080838493552af0b7bc90b1ac8e7dc1 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 07:06:37 -0400 Subject: [PATCH 06/19] docs: clarify /do-pr must run tests, commit, push, create PR, and update CHANGELOG non-interactively --- .opencode/command/do-pr.md | 77 +++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/.opencode/command/do-pr.md b/.opencode/command/do-pr.md index 9412b4d..272704b 100644 --- a/.opencode/command/do-pr.md +++ b/.opencode/command/do-pr.md @@ -3,17 +3,66 @@ description: Develop the changes for a new pull request agent: build --- -If the user has NOT previously ran the /start-pr command, exit early and ask them to run that command. - -1. Use the `todoread` tool to get the TODO list for the current issue -1. For each item in the TODO list: - 1. Carefully implement change - 1. Run relevant automated tests - 1. Refine based on test results - 1. Check off corresponding item in the issue spec - 1. Commit -1. After all items on the TODO list are complete: - 1. Push - 1. Create pull request - 1. Update changelog - 1. Push +IMPORTANT: This command must run the full non-interactive flow for creating a PR. That means it MUST run the test suite(s), commit any changes, push the branch, create the GitHub pull request, update `CHANGELOG.md` with the PR number, and push the changelog — all without asking the user for additional input. + +If the user has NOT previously run the `/start-pr` command, exit early and ask them to run that command. + +Required behavior (non-interactive flow) + +1. Use the `todoread` tool to get the TODO list for the current issue. +2. For each item in the TODO list: + - Implement the change as described in the TODO item. + - Run the relevant automated tests immediately after implementing the change. Tests must be run and pass before committing. Typical commands to run are: + - Unit/contract/integration (with race): + - `go test -race ./tests/unit ./tests/contract ./tests/integration` + - Performance tests (optional, without race): + - `go test ./tests/performance` + - If a change only affects unit tests, run the narrower set of packages to save time. + - If tests fail, refine the code until tests pass. Do not proceed to committing that TODO item until its tests pass. + - Once tests pass, update the spec (check off corresponding item) and commit the change locally using a descriptive conventional commit message (example `feat(7): add backup script`). + - Use: `git add -A && git commit -m ": "` +3. After all TODO items are completed and committed locally: + - Push the branch to the remote: + - `git push -u origin "$(git rev-parse --abbrev-ref HEAD)"` + - Create the pull request non-interactively using `gh` (GitHub CLI). Provide a clear title and a PR body via a HEREDOC to avoid shell quoting issues. Example: + - `gh pr create --title "" --body "$(cat <<'EOF'\n\nEOF\n)"` + - Retrieve the created PR number and URL to update `CHANGELOG.md`. + - Example to get the PR number: `gh pr view --json number,url --jq '.number'` + - Update `CHANGELOG.md` at the top (under the current unreleased section) with a single entry referencing the PR number in the repository style, for example: + - `- [#NN](https://github.com/kwila-cloud/simple-sync/pull/NN): Short description` + - Commit the `CHANGELOG.md` update and push the commit (it must be on the same branch so the changelog change is included in the PR): + - `git add CHANGELOG.md && git commit -m "chore: add changelog entry for PR #NN" && git push` + +Error handling and constraints + +- The command must NOT prompt the user for extra confirmation during the flow. If an operation would normally require input (for example, `gh pr create` in interactive mode), invoke the non-interactive flags and provide the input programmatically (HEREDOC or CLI flags). +- If tests fail, stop and report failures with the test output. Do not push or create the PR while tests are failing. +- If network push or GH CLI operations fail, surface the error and abort; do not attempt destructive recovery automatically. + +Examples + +- Commit and run tests for a single TODO item: + + ```bash + # implement change (edit files) + go test -race ./tests/unit ./tests/contract ./tests/integration + git add -A + git commit -m "feat(7): add backup script" + ``` + +- Create PR non-interactively and update changelog (example body uses HEREDOC): + + ```bash + git push -u origin "$(git rev-parse --abbrev-ref HEAD)" + gh pr create --title "7: Documentation and configuration updates" --body "$(cat <<'EOF'\n## Summary\n- Add backup/restore scripts and docs\n\n## Files\n- scripts/backup.sh\n- scripts/restore.sh\n- docs/data-persistence.mdx\nEOF\n)" + PR_NUMBER=$(gh pr view --json number --jq '.number') + sed -i "1i- [#$PR_NUMBER](https://github.com/kwila-cloud/simple-sync/pull/$PR_NUMBER): Documentation and configuration updates" CHANGELOG.md + git add CHANGELOG.md && git commit -m "chore: add changelog entry for PR #$PR_NUMBER" && git push + ``` + +Notes + +- Use HEREDOC with a single-quoted delimiter (`<<'EOF'`) when the PR body contains backticks or other shell-sensitive characters to avoid unintended shell expansion. +- Prefer running the narrowest test set that verifies the change to save CI time, but ensure integration/contract tests run when changes affect those areas. +- This command is intended to be used in a CI-friendly, non-interactive manner. Ensure any automated tooling invoked (tests, `gh`) is available in the environment that runs this command. + From aad87bcf1cc2b663548a4c69456dea8f2727657a Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 07:09:19 -0400 Subject: [PATCH 07/19] fix: do-pr command --- .opencode/command/do-pr.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.opencode/command/do-pr.md b/.opencode/command/do-pr.md index 272704b..9babf53 100644 --- a/.opencode/command/do-pr.md +++ b/.opencode/command/do-pr.md @@ -36,7 +36,6 @@ Required behavior (non-interactive flow) Error handling and constraints - The command must NOT prompt the user for extra confirmation during the flow. If an operation would normally require input (for example, `gh pr create` in interactive mode), invoke the non-interactive flags and provide the input programmatically (HEREDOC or CLI flags). -- If tests fail, stop and report failures with the test output. Do not push or create the PR while tests are failing. - If network push or GH CLI operations fail, surface the error and abort; do not attempt destructive recovery automatically. Examples @@ -47,14 +46,14 @@ Examples # implement change (edit files) go test -race ./tests/unit ./tests/contract ./tests/integration git add -A - git commit -m "feat(7): add backup script" + git commit -m "feat(storage): add backup script" ``` - Create PR non-interactively and update changelog (example body uses HEREDOC): ```bash git push -u origin "$(git rev-parse --abbrev-ref HEAD)" - gh pr create --title "7: Documentation and configuration updates" --body "$(cat <<'EOF'\n## Summary\n- Add backup/restore scripts and docs\n\n## Files\n- scripts/backup.sh\n- scripts/restore.sh\n- docs/data-persistence.mdx\nEOF\n)" + gh pr create --title "docs: documentation and configuration updates" --body "$(cat <<'EOF'\n## Summary\n- Add backup/restore scripts and docs\n\n## Files\n- scripts/backup.sh\n- scripts/restore.sh\n- docs/data-persistence.mdx\nEOF\n)" PR_NUMBER=$(gh pr view --json number --jq '.number') sed -i "1i- [#$PR_NUMBER](https://github.com/kwila-cloud/simple-sync/pull/$PR_NUMBER): Documentation and configuration updates" CHANGELOG.md git add CHANGELOG.md && git commit -m "chore: add changelog entry for PR #$PR_NUMBER" && git push @@ -64,5 +63,4 @@ Notes - Use HEREDOC with a single-quoted delimiter (`<<'EOF'`) when the PR body contains backticks or other shell-sensitive characters to avoid unintended shell expansion. - Prefer running the narrowest test set that verifies the change to save CI time, but ensure integration/contract tests run when changes affect those areas. -- This command is intended to be used in a CI-friendly, non-interactive manner. Ensure any automated tooling invoked (tests, `gh`) is available in the environment that runs this command. From c3bdc3b416990b782bd5a097859cfedae7cbe2cd Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 07:16:09 -0400 Subject: [PATCH 08/19] docs: Require confirmation in /start-pr before branching or writing TODOs; reference /do-pr --- .opencode/command/start-pr.md | 49 +++++++++++++++++++++++++---------- AGENTS.md | 20 ++++++++++++++ 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/.opencode/command/start-pr.md b/.opencode/command/start-pr.md index 47d4d87..96364a9 100644 --- a/.opencode/command/start-pr.md +++ b/.opencode/command/start-pr.md @@ -11,17 +11,38 @@ Use the user input as the issue number. If the user input is empty or invalid, prompt the user for the issue number. -1. Check the spec for the given issue in `specs/` -1. Determine the next incomplete section from the Task List -1. Create branch using format `{issue-number}-{section-name}` - - DO NOT create branch if already in the correct branch for the issue number and section name -1. Research codebase to understand what's needed for the section -1. Ask the user any clarifying questions needed to implement the section -1. Create a TODO list with the `todowrite` tool -1. Explain the TODO list to the user -1. Refine TODO list based on user feedback -1. Prompt the user to run `/do-pr` when they are ready - -Example usage: -- User: `/start-pr 7` -- Agent: Checks `specs/7-data-persistence.md`, finds next incomplete section, creates branch like `7-storage-interface-updates`, researches requirements, explains plan +Required behavior and confirmation flow + +1. Read the spec for the given issue in `specs/` and determine the next incomplete section from the Task List. +2. Before making any repository changes (branch creation, writing TODOs), ask the user a short set of clarifying questions and require explicit answers. These MUST include at minimum: + - Whether to create a new branch or stay on the current branch. + - If creating a branch, confirm the branch name format: `{issue-number}-{section-name}`. + - Whether to create the TODO list now or wait for additional instructions. +3. Branch creation rules: + - Create a new branch only when the current branch name does **not** already match the desired `{issue-number}-{section-name}` for the section. + - If the current branch already matches the section, do not create or switch branches. + - If the user explicitly requests to stay on the current branch, do not create a branch. +4. After the user confirms the clarifying questions, then (and only then): + - Create the branch if needed (see rule #3). + - Research the codebase to gather implementation notes for the section. + - Ask any additional clarifying questions that arise while researching (require answers before proceeding further). +5. Create a TODO list with the `todowrite` tool only after the user approved creating it. +6. Explain the TODO list to the user and allow them to request refinements. +7. When the plan/TODO list is approved by the user, instruct the user to run `/do-pr` to begin implementing the changes. Do not use the word “proceed” as the final prompt — always reference `/do-pr`. + +Example usage and flows + +- Typical create-branch flow: + - Agent: "Next incomplete section: `Documentation and Configuration Updates`. Create branch `7-documentation-and-configuration-updates` and prepare TODOs? (Y/n)" + - User: "Y" + - Agent: Creates branch, researches, creates TODOs, explains plan, then: "When ready to implement, run `/do-pr`." + +- Stay-on-current-branch flow: + - Agent: "Next incomplete section: `Docs`. Current branch is `7-documentation-and-configuration-updates`. Create a new branch `7-docs` or stay on current branch? (create/stay)" + - User: "stay" + - Agent: Does not create a branch, asks whether to create TODOs now, and if confirmed, creates TODOs only. + +Notes + +- The command MUST NOT make repository modifications before receiving the user's answers to the clarifying questions. +- All user-facing prompts produced by this command must end by instructing the user to run `/do-pr` when they want the agent to start implementation. diff --git a/AGENTS.md b/AGENTS.md index b7343c2..3a3ac49 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -190,6 +190,26 @@ Opencode commands are defined as separate markdown files in `.opencode/command/` See `.opencode/command/` directory for examples. +**Start-pr command rules (agent-specific guidance):** + +- The `/start-pr` command reads the issue spec and prepares a plan for a PR. It MUST ask clarifying questions and receive explicit user answers before making any repository changes (branch creation or writing TODOs). +- Branch creation behavior: + - Create a new branch only when the current branch does **not** match the required `{issue-number}-{section-name}` for the next incomplete section in the spec. + - If the current branch already matches the desired section branch name, do NOT create or switch branches. + - If the user explicitly requests to stay on the current branch, do not create a branch even if the names differ. +- The command must never use the informal phrase “proceed” as the final prompt. Instead, after the plan is approved, instruct users to run `/do-pr` to begin implementation. +- Example flows: + - Create branch: + - Agent: "Next incomplete section: `Documentation and Configuration Updates`. Create branch `7-documentation-and-configuration-updates` and prepare TODOs? (Y/n)" + - User: "Y" + - Agent: Creates branch, creates TODOs, explains plan, then: "When ready to implement, run `/do-pr`." + - Stay on current branch: + - Agent: "Next incomplete section: `Docs`. Current branch is `7-documentation-and-configuration-updates`. Create a new branch `7-docs` or stay on current branch? (create/stay)" + - User: "stay" + - Agent: Does not create branch, asks whether to create TODOs now, and if confirmed, creates TODOs only. + +See `.opencode/command/start-pr.md` for the exact prompt wording and confirmation flow. + **Common mistake to avoid:** Do NOT add command documentation to AGENTS.md. Commands belong in their own files in `.opencode/command/`. ### Naming Scheme From cf3b8df7a4937e3475e4531d3a62fcb30b2ecd69 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 07:17:21 -0400 Subject: [PATCH 09/19] docs: Move /start-pr guidance into command file; remove duplicate AGENTS.md section --- AGENTS.md | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3a3ac49..b7343c2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -190,26 +190,6 @@ Opencode commands are defined as separate markdown files in `.opencode/command/` See `.opencode/command/` directory for examples. -**Start-pr command rules (agent-specific guidance):** - -- The `/start-pr` command reads the issue spec and prepares a plan for a PR. It MUST ask clarifying questions and receive explicit user answers before making any repository changes (branch creation or writing TODOs). -- Branch creation behavior: - - Create a new branch only when the current branch does **not** match the required `{issue-number}-{section-name}` for the next incomplete section in the spec. - - If the current branch already matches the desired section branch name, do NOT create or switch branches. - - If the user explicitly requests to stay on the current branch, do not create a branch even if the names differ. -- The command must never use the informal phrase “proceed” as the final prompt. Instead, after the plan is approved, instruct users to run `/do-pr` to begin implementation. -- Example flows: - - Create branch: - - Agent: "Next incomplete section: `Documentation and Configuration Updates`. Create branch `7-documentation-and-configuration-updates` and prepare TODOs? (Y/n)" - - User: "Y" - - Agent: Creates branch, creates TODOs, explains plan, then: "When ready to implement, run `/do-pr`." - - Stay on current branch: - - Agent: "Next incomplete section: `Docs`. Current branch is `7-documentation-and-configuration-updates`. Create a new branch `7-docs` or stay on current branch? (create/stay)" - - User: "stay" - - Agent: Does not create branch, asks whether to create TODOs now, and if confirmed, creates TODOs only. - -See `.opencode/command/start-pr.md` for the exact prompt wording and confirmation flow. - **Common mistake to avoid:** Do NOT add command documentation to AGENTS.md. Commands belong in their own files in `.opencode/command/`. ### Naming Scheme From d5e980d0f31df4f510b84b05c8b28c0551937ae7 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 07:22:33 -0400 Subject: [PATCH 10/19] docs: update commands --- .opencode/command/do-pr.md | 38 +++++++---------------------------- .opencode/command/start-pr.md | 37 ++++++++-------------------------- 2 files changed, 15 insertions(+), 60 deletions(-) diff --git a/.opencode/command/do-pr.md b/.opencode/command/do-pr.md index 9babf53..e82f8d0 100644 --- a/.opencode/command/do-pr.md +++ b/.opencode/command/do-pr.md @@ -5,13 +5,13 @@ agent: build IMPORTANT: This command must run the full non-interactive flow for creating a PR. That means it MUST run the test suite(s), commit any changes, push the branch, create the GitHub pull request, update `CHANGELOG.md` with the PR number, and push the changelog — all without asking the user for additional input. -If the user has NOT previously run the `/start-pr` command, exit early and ask them to run that command. +If the user has NOT previously run the `/start-pr` command, prompt them for the issue number to work on. Required behavior (non-interactive flow) -1. Use the `todoread` tool to get the TODO list for the current issue. -2. For each item in the TODO list: - - Implement the change as described in the TODO item. +1. Read the spec for the given issue in `specs/` and determine the next incomplete section from the Task List. +2. For each task in the incomplete section: + - Implement the task. - Run the relevant automated tests immediately after implementing the change. Tests must be run and pass before committing. Typical commands to run are: - Unit/contract/integration (with race): - `go test -race ./tests/unit ./tests/contract ./tests/integration` @@ -21,7 +21,7 @@ Required behavior (non-interactive flow) - If tests fail, refine the code until tests pass. Do not proceed to committing that TODO item until its tests pass. - Once tests pass, update the spec (check off corresponding item) and commit the change locally using a descriptive conventional commit message (example `feat(7): add backup script`). - Use: `git add -A && git commit -m ": "` -3. After all TODO items are completed and committed locally: +3. After all task items for the current section are completed and committed locally: - Push the branch to the remote: - `git push -u origin "$(git rev-parse --abbrev-ref HEAD)"` - Create the pull request non-interactively using `gh` (GitHub CLI). Provide a clear title and a PR body via a HEREDOC to avoid shell quoting issues. Example: @@ -32,35 +32,11 @@ Required behavior (non-interactive flow) - `- [#NN](https://github.com/kwila-cloud/simple-sync/pull/NN): Short description` - Commit the `CHANGELOG.md` update and push the commit (it must be on the same branch so the changelog change is included in the PR): - `git add CHANGELOG.md && git commit -m "chore: add changelog entry for PR #NN" && git push` + - Ask the user for code review feedback on the new pull request. + - DO NOT suggest starting on the next section of the task list. Error handling and constraints - The command must NOT prompt the user for extra confirmation during the flow. If an operation would normally require input (for example, `gh pr create` in interactive mode), invoke the non-interactive flags and provide the input programmatically (HEREDOC or CLI flags). - If network push or GH CLI operations fail, surface the error and abort; do not attempt destructive recovery automatically. -Examples - -- Commit and run tests for a single TODO item: - - ```bash - # implement change (edit files) - go test -race ./tests/unit ./tests/contract ./tests/integration - git add -A - git commit -m "feat(storage): add backup script" - ``` - -- Create PR non-interactively and update changelog (example body uses HEREDOC): - - ```bash - git push -u origin "$(git rev-parse --abbrev-ref HEAD)" - gh pr create --title "docs: documentation and configuration updates" --body "$(cat <<'EOF'\n## Summary\n- Add backup/restore scripts and docs\n\n## Files\n- scripts/backup.sh\n- scripts/restore.sh\n- docs/data-persistence.mdx\nEOF\n)" - PR_NUMBER=$(gh pr view --json number --jq '.number') - sed -i "1i- [#$PR_NUMBER](https://github.com/kwila-cloud/simple-sync/pull/$PR_NUMBER): Documentation and configuration updates" CHANGELOG.md - git add CHANGELOG.md && git commit -m "chore: add changelog entry for PR #$PR_NUMBER" && git push - ``` - -Notes - -- Use HEREDOC with a single-quoted delimiter (`<<'EOF'`) when the PR body contains backticks or other shell-sensitive characters to avoid unintended shell expansion. -- Prefer running the narrowest test set that verifies the change to save CI time, but ensure integration/contract tests run when changes affect those areas. - diff --git a/.opencode/command/start-pr.md b/.opencode/command/start-pr.md index 96364a9..da9cfaa 100644 --- a/.opencode/command/start-pr.md +++ b/.opencode/command/start-pr.md @@ -14,35 +14,14 @@ If the user input is empty or invalid, prompt the user for the issue number. Required behavior and confirmation flow 1. Read the spec for the given issue in `specs/` and determine the next incomplete section from the Task List. -2. Before making any repository changes (branch creation, writing TODOs), ask the user a short set of clarifying questions and require explicit answers. These MUST include at minimum: - - Whether to create a new branch or stay on the current branch. - - If creating a branch, confirm the branch name format: `{issue-number}-{section-name}`. - - Whether to create the TODO list now or wait for additional instructions. -3. Branch creation rules: +2. Branch creation rules: - Create a new branch only when the current branch name does **not** already match the desired `{issue-number}-{section-name}` for the section. - If the current branch already matches the section, do not create or switch branches. - If the user explicitly requests to stay on the current branch, do not create a branch. -4. After the user confirms the clarifying questions, then (and only then): - - Create the branch if needed (see rule #3). - - Research the codebase to gather implementation notes for the section. - - Ask any additional clarifying questions that arise while researching (require answers before proceeding further). -5. Create a TODO list with the `todowrite` tool only after the user approved creating it. -6. Explain the TODO list to the user and allow them to request refinements. -7. When the plan/TODO list is approved by the user, instruct the user to run `/do-pr` to begin implementing the changes. Do not use the word “proceed” as the final prompt — always reference `/do-pr`. - -Example usage and flows - -- Typical create-branch flow: - - Agent: "Next incomplete section: `Documentation and Configuration Updates`. Create branch `7-documentation-and-configuration-updates` and prepare TODOs? (Y/n)" - - User: "Y" - - Agent: Creates branch, researches, creates TODOs, explains plan, then: "When ready to implement, run `/do-pr`." - -- Stay-on-current-branch flow: - - Agent: "Next incomplete section: `Docs`. Current branch is `7-documentation-and-configuration-updates`. Create a new branch `7-docs` or stay on current branch? (create/stay)" - - User: "stay" - - Agent: Does not create a branch, asks whether to create TODOs now, and if confirmed, creates TODOs only. - -Notes - -- The command MUST NOT make repository modifications before receiving the user's answers to the clarifying questions. -- All user-facing prompts produced by this command must end by instructing the user to run `/do-pr` when they want the agent to start implementation. +3. Research the codebase to gather information about the change. +4. Ask the user clarifying questions. + - Clearly number the questions. + - Clearly letter the options for each question. +5. Update the Task List section with any new updates based on your research and the user's answers. +6. Explain the current Task List section to the user. +7. When the Task List section is approved by the user, instruct the user to run `/do-pr` to begin implementing the changes. Do not use the word “proceed” as the final prompt — always reference `/do-pr`. From 6705285963d7e934af28d0cccba51fdcf65aad61 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 08:02:45 -0400 Subject: [PATCH 11/19] docs(7): move data-persistence doc to site content and note restore script --- specs/7-data-persistence.md | 11 ++++---- src/content/docs/data-persistence.mdx | 38 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/content/docs/data-persistence.mdx diff --git a/specs/7-data-persistence.md b/specs/7-data-persistence.md index fc6d001..e211b75 100644 --- a/specs/7-data-persistence.md +++ b/specs/7-data-persistence.md @@ -79,11 +79,12 @@ Encryption at rest will be addressed separately (issue #17) using SQLCipher or f - [x] Validate concurrent access and large dataset handling ### Documentation and Configuration Updates -- [ ] Update Docker configuration for data persistence -- [ ] Update AGENTS.md with SQLite storage information -- [ ] Update README.md with data persistence features and setup instructions -- [ ] Update user-facing documentation in docs/ with SQLite configuration -- [ ] Document backup/restore procedures and security considerations +- [x] Update Docker configuration for data persistence +- [ ] Update AGENTS.md with SQLite storage information (relocate or adjust; new info is in wrong section) +- [x] Update README.md with data persistence features and setup instructions +- [ ] Update user-facing documentation in `src/content/docs` with SQLite configuration (move `docs/data-persistence.mdx` into `src/content/docs`) +- [ ] Document backup/restore procedures and security considerations (restore script still needs work) +- [ ] Verify and improve `scripts/backup.sh` and `scripts/restore.sh` (ensure `restore.sh` behavior and examples) ### Clean Up - [ ] Handle remaining TODO comments for issue #7 diff --git a/src/content/docs/data-persistence.mdx b/src/content/docs/data-persistence.mdx new file mode 100644 index 0000000..f233744 --- /dev/null +++ b/src/content/docs/data-persistence.mdx @@ -0,0 +1,38 @@ +--- +title: Data Persistence +--- + +## Data Persistence and Backups + +This project uses SQLite for persistent storage. By default the service stores its database file in `./data/simple-sync.db` when you run via Docker Compose. + +### Running with Docker Compose + +The repository ships a `docker-compose.yml` that bind-mounts `./data` into the container (`./data:/app/data`). This keeps the DB file on the host so you can inspect, back up, or move it easily. + +### Backups + +Use the supplied helper scripts: + +- `./scripts/backup.sh [--stop] [path-to-db]` — copies the DB file to `./backups/` with a timestamped filename. Use `--stop` to stop the container during backup for safety. +- `./scripts/restore.sh [--stop]` — restores a backup into `./data/simple-sync.db`. The existing DB (if any) will be moved aside before restore. + +Example workflow: + +```bash +# Stop, backup, and start using the scripts +./scripts/backup.sh --stop +docker compose up -d +``` + +### Security Considerations + +- The database file contains sensitive data. Store backups securely and limit filesystem access. +- For production, consider encrypting the filesystem or using SQLCipher (see issue #17). +- Ensure regular backups and test restores periodically. + +### Developer notes + +- Building the binary with `github.com/mattn/go-sqlite3` requires a C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1`. + + From 414da2d5ef95b73c565a081a455b24d04697bedc Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 08:04:10 -0400 Subject: [PATCH 12/19] chore: add changelog entry for PR #62 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 882a46a..86399c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Release History ## [0.4.0] - unreleased +- [#62](https://github.com/kwila-cloud/simple-sync/pull/62): docs(7): documentation and restore script fixes for data persistence - [#61](https://github.com/kwila-cloud/simple-sync/pull/61): Add performance and concurrency tests for SQLite storage - [#60](https://github.com/kwila-cloud/simple-sync/pull/60): Implement SQLite setup token and API key storage - [#59](https://github.com/kwila-cloud/simple-sync/pull/59): Implement SQLite ACL rule storage From 4e3ae854a25d2933e31eb6168c03235df0f7a9c4 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 08:09:53 -0400 Subject: [PATCH 13/19] docs: clarify PR title/description and changelog rules to avoid issue-number errors --- AGENTS.md | 58 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b7343c2..7a9e529 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -150,31 +150,61 @@ See `specs/7-data-persistence.md` for a well-structured specification that: - **Recommendation:** When programmatically constructing search patterns, either validate the regex before use or default to fixed-string searches. If you are unsure whether a pattern contains regex metacharacters, use `-F` to avoid surprises. +### PR Title & Description Rules +- **Always inspect the full diff for the branch before creating a PR.** Use Git to view changes against the base branch and confirm the final, combined diff that will become the PR. + + - View commits on your branch relative to `main`: + - `git fetch origin && git log --oneline origin/main...HEAD` + - View a concise file/status diff against `main`: + - `git fetch origin && git diff --name-status origin/main...HEAD` + - View a human-readable patch summary before creating the PR: + - `git fetch origin && git diff --stat origin/main...HEAD` + - View the full patch if needed: + - `git fetch origin && git diff origin/main...HEAD` + +- **Title rules:** + - The PR title must be a short, descriptive summary of the change and MUST NOT include the issue number. + - Example — incorrect: `docs(7): documentation and restore script fixes for data persistence` + - Example — correct: `docs: documentation and restore script fixes for data persistence` + +- **Description rules:** + - The PR body/description MUST include the issue number (and link) that the PR addresses. Prefer an explicit `Fixes #` or `Related to #` line. + - Example body snippet: + + Issue: https://github.com/kwila-cloud/simple-sync/issues/7 + + This PR moves the data-persistence doc into the site content and adds a checklist to verify `restore.sh` behavior. + + Fixes #7 + +- **How to get the final PR number non-interactively:** + - After creating the PR, capture the assigned number: + - `gh pr view --json number,url --jq '.number'` (use the branch name if needed) + ### Changelog -- **ALWAYS add a new line to `CHANGELOG.md` for each new *pull request* (PR).** Do not link to the issue number — reference the PR number. -- Document new features, enhancements, bug fixes, and breaking changes -- Follow the existing format with PR links and clear descriptions (see examples below) -- Keep entries concise but descriptive for users and maintainers -- **IMPORTANT**: Always verify the actual PR details before updating the changelog. Use `gh pr view ` or `gh pr view ` to confirm the PR number, title, and changed files. +- **ALWAYS add a new line to `CHANGELOG.md` for each new *pull request* (PR).** Do not include or link to the issue number — reference the PR number only. +- Document new features, enhancements, bug fixes, and breaking changes. +- Follow the existing format with PR links and clear descriptions (see examples below). +- Keep entries concise but descriptive for users and maintainers. +- **IMPORTANT**: Always verify the actual PR details **and the PR title** before updating the changelog. Use `gh pr view ` or `gh pr view ` to confirm the PR number, title, and changed files. - **CRITICAL**: Add exactly ONE entry per PR. Never add multiple entries for the same pull request, even if the PR contains multiple types of changes. Combine all changes into a single, concise description. Examples (incorrect vs correct): -- Incorrect (links to issue instead of PR): +- Incorrect (links to issue rather than PR, or includes issue numbers in the text): - `- [#7](https://github.com/kwila-cloud/simple-sync/issues/7): Implement ACL rule storage (CreateAclRule, GetAclRules)` -- Correct (match existing style — use PR link and number): +- Correct (match existing style — use PR link and number, no issue numbers in entry): - `- [#59](https://github.com/kwila-cloud/simple-sync/pull/59): Implement ACL rule storage (CreateAclRule, GetAclRules)` Recommended workflow to avoid mistakes: -1. Create the PR on the branch (`gh pr create`), or push the branch and open the PR on GitHub. -2. Immediately run `gh pr view --json number,url,title --jq '.number'` or `gh pr view ` to retrieve the assigned PR number. - - Example: `gh pr view 7-acl-rule-storage --json number,url,title` -3. Edit `CHANGELOG.md` at the top (under the current unreleased version) and add a single line using the PR number as shown in the "Correct" example above. -4. Commit the changelog update to the same branch so the changelog change is included in the PR. -5. Push the branch and verify the PR body/changed files if necessary. +1. Inspect the full diff using the `git` commands above and confirm the intended changes. +2. Create the PR non-interactively using `gh pr create` with a title (no issue number) and a body that includes the issue link/number. +3. Immediately run `gh pr view --json number,url,title --jq '.number'` to get the PR number. +4. Update `CHANGELOG.md` at the top (under the current unreleased version) with a single entry referencing the **PR number only**. +5. Commit the changelog update to the same branch so the changelog change is included in the PR. Notes: - The changelog should always reference the PR number (not the issue number) because the PR is the canonical unit that contains the implemented changes and the exact diff reviewers will see. @@ -183,6 +213,8 @@ Notes: ### Opencode Commands +### Opencode Commands + Opencode commands are defined as separate markdown files in `.opencode/command/`. Each command file should: - Have a `description` and `agent` in the frontmatter - Contain the command logic and usage instructions From 30ee88fe6652f815beb286b2b782fb01981284b9 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 08:11:50 -0400 Subject: [PATCH 14/19] chore: fix changelog entry for PR #62 (remove issue number from entry) --- CHANGELOG.md | 2 +- docs/data-persistence.mdx | 37 ------------------------------------- 2 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 docs/data-persistence.mdx diff --git a/CHANGELOG.md b/CHANGELOG.md index 86399c3..3be0643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Release History ## [0.4.0] - unreleased -- [#62](https://github.com/kwila-cloud/simple-sync/pull/62): docs(7): documentation and restore script fixes for data persistence +- [#62](https://github.com/kwila-cloud/simple-sync/pull/62): docs: documentation and restore script fixes for data persistence - [#61](https://github.com/kwila-cloud/simple-sync/pull/61): Add performance and concurrency tests for SQLite storage - [#60](https://github.com/kwila-cloud/simple-sync/pull/60): Implement SQLite setup token and API key storage - [#59](https://github.com/kwila-cloud/simple-sync/pull/59): Implement SQLite ACL rule storage diff --git a/docs/data-persistence.mdx b/docs/data-persistence.mdx deleted file mode 100644 index d87d97c..0000000 --- a/docs/data-persistence.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Data Persistence ---- - -## Data Persistence and Backups - -This project uses SQLite for persistent storage. By default the service stores its database file in `./data/simple-sync.db` when you run via Docker Compose. - -### Running with Docker Compose - -The repository ships a `docker-compose.yml` that bind-mounts `./data` into the container (`./data:/app/data`). This keeps the DB file on the host so you can inspect, back up, or move it easily. - -### Backups - -Use the supplied helper scripts: - -- `./scripts/backup.sh [--stop] [path-to-db]` — copies the DB file to `./backups/` with a timestamped filename. Use `--stop` to stop the container during backup for safety. -- `./scripts/restore.sh [--stop]` — restores a backup into `./data/simple-sync.db`. The existing DB (if any) will be moved aside before restore. - -Example workflow: - -```bash -# Stop, backup, and start using the scripts -./scripts/backup.sh --stop -docker compose up -d -``` - -### Security Considerations - -- The database file contains sensitive data. Store backups securely and limit filesystem access. -- For production, consider encrypting the filesystem or using SQLCipher (see issue #17). -- Ensure regular backups and test restores periodically. - -### Developer notes - -- Building the binary with `github.com/mattn/go-sqlite3` requires a C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1`. - From 2bbe660e83cb6d1ace9efc73a1ccc93da43c8857 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 08:15:09 -0400 Subject: [PATCH 15/19] feat(7): add --dir option to backup script and move AGENTS guidance --- CHANGELOG.md | 2 +- scripts/backup.sh | 48 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3be0643..b1fbd8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Release History ## [0.4.0] - unreleased -- [#62](https://github.com/kwila-cloud/simple-sync/pull/62): docs: documentation and restore script fixes for data persistence +- [#62](https://github.com/kwila-cloud/simple-sync/pull/62): Add storage documentation - [#61](https://github.com/kwila-cloud/simple-sync/pull/61): Add performance and concurrency tests for SQLite storage - [#60](https://github.com/kwila-cloud/simple-sync/pull/60): Implement SQLite setup token and API key storage - [#59](https://github.com/kwila-cloud/simple-sync/pull/59): Implement SQLite ACL rule storage diff --git a/scripts/backup.sh b/scripts/backup.sh index 4f7f905..532daa8 100644 --- a/scripts/backup.sh +++ b/scripts/backup.sh @@ -2,22 +2,50 @@ set -euo pipefail # Simple Sync backup script -# Usage: ./scripts/backup.sh [--stop] [path-to-db] +# Usage: ./scripts/backup.sh [--stop] [--dir ] [path-to-db] # If --stop is provided, the script will stop the docker-compose service before copying and restart it afterwards. +# If --dir is provided, it specifies the directory to store backups (defaults to ./backups). STOP=false +BACKUP_DIR="./backups" DB_PATH="./data/simple-sync.db" +DB_PATH_PROVIDED=false -if [ "${1:-}" = "--stop" ]; then - STOP=true - shift -fi +while [ "$#" -gt 0 ]; do + case "$1" in + --stop) + STOP=true + shift + ;; + --dir) + if [ -z "${2:-}" ]; then + echo "Error: --dir requires a directory argument" + exit 2 + fi + BACKUP_DIR="$2" + shift 2 + ;; + --dir=*) + BACKUP_DIR="${1#--dir=}" + shift + ;; + --help|-h) + echo "Usage: $0 [--stop] [--dir ] [path-to-db]" + exit 0 + ;; + *) + if [ "$DB_PATH_PROVIDED" = false ]; then + DB_PATH="$1" + DB_PATH_PROVIDED=true + shift + else + echo "Unknown argument: $1" + exit 2 + fi + ;; + esac +done -if [ "$#" -ge 1 ]; then - DB_PATH="$1" -fi - -BACKUP_DIR="./backups" mkdir -p "$BACKUP_DIR" if [ ! -f "$DB_PATH" ]; then From 0e97b9b6db90a4439ce94fee20f815383071fb57 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 08:16:50 -0400 Subject: [PATCH 16/19] =?UTF-8?q?feat(7):=20address=20PR=20feedback=20?= =?UTF-8?q?=E2=80=94=20relocate=20AGENTS=20storage=20notes,=20add=20--dir?= =?UTF-8?q?=20to=20backup.sh,=20update=20docs=20and=20changelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7a9e529..e4c48df 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,16 +14,14 @@ Simple-sync is a lightweight REST API built in Go that provides event storage an - Event storage with timestamps and metadata - ACL-based permission system (read/write permissions) -### GitHub Data Access - -- **Storage & Docker notes (for future agents):** - - The project uses SQLite for persistent storage; production/dev processes expect a local file under `./data` by default (`./data/simple-sync.db`). - - Docker Compose is configured to bind-mount `./data` into the container (`./data:/app/data`) so the DB file is stored on the host. This is the recommended setup for development and simple deployments because it makes backups and inspection straightforward. - - If you need a Docker-managed volume, a named volume `simple-sync-data` exists in `docker-compose.yml` (commented). Using a named volume is fine for environments where host access is not required, but it makes manual backups/restores less obvious. - - Building the Go binary with `github.com/mattn/go-sqlite3` requires a system C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1` during build. CI workflows already install `libsqlite3-dev` where needed. - - For backups, there are helper scripts in `./scripts/backup.sh` and `./scripts/restore.sh` that copy the DB file from `./data` to `./backups` and restore it safely; future agents should prefer these scripts for simple backup/restore workflows. +### Storage & Docker notes (for future agents): +- The project uses SQLite for persistent storage; production/dev processes expect a local file under `./data` by default (`./data/simple-sync.db`). +- Docker Compose is configured to bind-mount `./data` into the container (`./data:/app/data`) so the DB file is stored on the host. This is the recommended setup for development and simple deployments because it makes backups and inspection straightforward. +- If you need a Docker-managed volume, a named volume `simple-sync-data` exists in `docker-compose.yml` (commented). Using a named volume is fine for environments where host access is not required, but it makes manual backups/restores less obvious. +- Building the Go binary with `github.com/mattn/go-sqlite3` requires a system C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1` during build. CI workflows already install `libsqlite3-dev` where needed. +- For backups, there are helper scripts in `./scripts/backup.sh` and `./scripts/restore.sh` that copy the DB file from `./data` to `./backups` and restore it safely; future agents should prefer these scripts for simple backup/restore workflows. -### Project Knowledge +### GitHub Data Access - **ALWAYS use GitHub CLI for GitHub data** - NEVER use webfetch for issues, PRs, or other GitHub information - **Issue information**: Use `gh issue view ` From 7160a472e50aa0ffeb47d0f02ec6533ce8be1dc2 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 19:43:26 -0400 Subject: [PATCH 17/19] docs: improve AGENTs.md layout --- AGENTS.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e4c48df..42aeac1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,13 +14,6 @@ Simple-sync is a lightweight REST API built in Go that provides event storage an - Event storage with timestamps and metadata - ACL-based permission system (read/write permissions) -### Storage & Docker notes (for future agents): -- The project uses SQLite for persistent storage; production/dev processes expect a local file under `./data` by default (`./data/simple-sync.db`). -- Docker Compose is configured to bind-mount `./data` into the container (`./data:/app/data`) so the DB file is stored on the host. This is the recommended setup for development and simple deployments because it makes backups and inspection straightforward. -- If you need a Docker-managed volume, a named volume `simple-sync-data` exists in `docker-compose.yml` (commented). Using a named volume is fine for environments where host access is not required, but it makes manual backups/restores less obvious. -- Building the Go binary with `github.com/mattn/go-sqlite3` requires a system C toolchain and headers (`libsqlite3-dev`) and `CGO_ENABLED=1` during build. CI workflows already install `libsqlite3-dev` where needed. -- For backups, there are helper scripts in `./scripts/backup.sh` and `./scripts/restore.sh` that copy the DB file from `./data` to `./backups` and restore it safely; future agents should prefer these scripts for simple backup/restore workflows. - ### GitHub Data Access - **ALWAYS use GitHub CLI for GitHub data** - NEVER use webfetch for issues, PRs, or other GitHub information @@ -262,3 +255,9 @@ Prefer `for i := range n` (Go 1.22+) over `for i := 0; i < n; i++` when iteratin - ❌ Bad: Creating custom string formatting helpers 4. **When in doubt**: If you're about to write a helper function, first check the Go standard library documentation for existing solutions + +### SQLite Storage +- The project uses SQLite for persistent storage; production/dev processes expect a local file under `./data` by default (`./data/simple-sync.db`). +- Docker Compose is configured to bind-mount `./data` into the container (`./data:/app/data`) so the DB file is stored on the host. This is the recommended setup for development and simple deployments because it makes backups and inspection straightforward. +- If you need a Docker-managed volume, a named volume `simple-sync-data` exists in `docker-compose.yml` (commented). Using a named volume is fine for environments where host access is not required, but it makes manual backups/restores less obvious. + From b2fe5beee4cab0fcecefaf2aa012c028a2429704 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 19:44:34 -0400 Subject: [PATCH 18/19] docs(7): document --dir option for backup script in docs and README --- README.md | 2 +- src/content/docs/data-persistence.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7aed697..7b9abd4 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ The Docker Compose configuration mounts a local `./data` directory into the cont If you prefer Docker-managed storage, a named volume `simple-sync-data` is declared in `docker-compose.yml`; you can switch to it by uncommenting the named volume line and removing the `./data` bind mount. Backup and restore helper scripts are provided in `./scripts`: -- `./scripts/backup.sh [--stop] [path-to-db]` — copy the DB file to `./backups/` (use `--stop` to stop the container during backup) +- `./scripts/backup.sh [--stop] [--dir ] [path-to-db]` — copy the DB file to `./backups/` (or specified directory) (use `--stop` to stop the container during backup) - `./scripts/restore.sh [--stop]` — restore a backup into `./data/simple-sync.db` (moves the existing DB aside first) Example (take a backup and then start): diff --git a/src/content/docs/data-persistence.mdx b/src/content/docs/data-persistence.mdx index f233744..1228a7e 100644 --- a/src/content/docs/data-persistence.mdx +++ b/src/content/docs/data-persistence.mdx @@ -14,7 +14,7 @@ The repository ships a `docker-compose.yml` that bind-mounts `./data` into the c Use the supplied helper scripts: -- `./scripts/backup.sh [--stop] [path-to-db]` — copies the DB file to `./backups/` with a timestamped filename. Use `--stop` to stop the container during backup for safety. +- `./scripts/backup.sh [--stop] [--dir ] [path-to-db]` — copies the DB file to `./backups/` (or specified directory) with a timestamped filename. Use `--stop` to stop the container during backup for safety. - `./scripts/restore.sh [--stop]` — restores a backup into `./data/simple-sync.db`. The existing DB (if any) will be moved aside before restore. Example workflow: From 38c6dedcc0628c4d4a3d5c8989b9d473bcabdaa1 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 19:49:08 -0400 Subject: [PATCH 19/19] docs: updates --- AGENTS.md | 3 --- specs/7-data-persistence.md | 7 +++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 42aeac1..9c273ba 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -204,8 +204,6 @@ Notes: ### Opencode Commands -### Opencode Commands - Opencode commands are defined as separate markdown files in `.opencode/command/`. Each command file should: - Have a `description` and `agent` in the frontmatter - Contain the command logic and usage instructions @@ -227,7 +225,6 @@ See `.opencode/command/` directory for examples. ### Idiomtic Go - #### Looping Prefer `for i := range n` (Go 1.22+) over `for i := 0; i < n; i++` when iterating a fixed integer count; prefer `for i := range slice` when iterating slices. diff --git a/specs/7-data-persistence.md b/specs/7-data-persistence.md index e211b75..ae9daf1 100644 --- a/specs/7-data-persistence.md +++ b/specs/7-data-persistence.md @@ -80,11 +80,10 @@ Encryption at rest will be addressed separately (issue #17) using SQLCipher or f ### Documentation and Configuration Updates - [x] Update Docker configuration for data persistence -- [ ] Update AGENTS.md with SQLite storage information (relocate or adjust; new info is in wrong section) +- [x] Update AGENTS.md with SQLite storage information - [x] Update README.md with data persistence features and setup instructions -- [ ] Update user-facing documentation in `src/content/docs` with SQLite configuration (move `docs/data-persistence.mdx` into `src/content/docs`) -- [ ] Document backup/restore procedures and security considerations (restore script still needs work) -- [ ] Verify and improve `scripts/backup.sh` and `scripts/restore.sh` (ensure `restore.sh` behavior and examples) +- [x] Update user-facing documentation in `src/content/docs` with SQLite configuration +- [x] Document backup/restore ### Clean Up - [ ] Handle remaining TODO comments for issue #7