things-cloud-sdk v0.6.0
v0.6.0 adds verified ordinary Task7 writes to the CLI, recovers tasks skipped by older readers, and repairs Unicode note replay. It also prevents malformed writes and fixes future scheduling and container moves.
Highlights
Task7 writes with an explicit safety boundary
- CLI task creates and modifications now use Task7. Existing SDK callers keep
ItemKindTask == "Task6"; explicitItemKindTask7writes are supported through the validated contract. - Validate full creation payloads and sparse updates before network access, including JSON types, coherent scheduling/completion fields, canonical references, duplicate keys, and Unicode encoding.
- Before a Task7 update, inspect raw history once per write batch and reject recurring templates/instances, missing or ambiguous targets, and insufficient recurrence metadata before posting any operation.
- Use the checked history head as the commit ancestor, with no automatic retry after a failed write.
- Keep Tag4, Area3, ChecklistItem3, and Tombstone2 formats unchanged. No account-wide task or history rewrite is performed.
Task7 reads, Unicode notes, and recovery
- Read Task6/Task7 events on the same task identity, preserving supported notes and relationships.
- Apply note deltas using UTF-8 byte offsets. A native Unicode edit that previously produced
SecoUpdatene.now correctly producesUpdated line.. - Reject invalid UTF-8 note results before memory-batch mutation or SQLite transaction commit. Preserve deletion ordering, including legacy tombstones.
- Replay generation 3 repairs already-caught-up CLI caches and SQLite state built by older readers. Preserve existing SQLite audit rows and original cache backups.
- Keep omitted properties distinct from explicit nulls and
srstart dates separate fromtirordering reference dates. - Reject unknown future task kinds instead of advancing an incomplete read cursor.
Correct scheduling and moves
- Future
--scheduledtask dates go to Upcoming using the local civil calendar day. Explicit--whenremains authoritative within the supported write scope. - Preserve explicit scheduling during creation with area, project, or heading assignment.
- Moving to an area now clears old project/heading links; moving to a project clears old area/heading links.
- Reject ambiguous edits combining area with project or heading. Project plus heading remains supported.
Input and SDK hardening
- Validate canonical IDs, dates, schedule names, task types, batch fields, trailing input, and effective options after overrides before commits.
- Preserve whole-batch rejection when any operation is invalid or a Task7 target fails preflight.
- Return malformed-request construction errors instead of panicking.
- Remove redundant request setup and the obsolete unchecked note parser without adding dependencies.
Upgrade and compatibility
The first read after upgrading may replay full cloud history. The CLI saves the old cache as <cache-path>.before-replay-<random>.bak and replaces it atomically after success. SQLite creates a consistent <database-path>.task7-backup-<random> snapshot and installs recovered state transactionally. Call Sync() before relying on database queries; Open() remains offline.
Recovery preserves existing audit row IDs, timestamps, and payloads, and suppresses duplicate historical notifications. Failed recovery leaves previous state available for retry. Backups use owner-only permissions; identical SQLite snapshots are deduplicated by full content. Allow replay memory and temporary space for a database snapshot.
Task7 CLI updates now add a full-history preflight. Older or sparse histories without explicit rr, rp, and rt are refused even if the task may be ordinary; the checker does not guess or fall back automatically to Task6. Existing SDK Task6 callers retain their prior behavior. Project and heading creates are limited to Anytime in this first Task7 scope.
Go 1.25.0 remains required. No dependencies or binary assets were added; this release provides source archives.
Remaining limits
- Recurrence configuration and recurring-instance writes, modern non-null
rp, direct Task7 note-delta writes, and direct Task7 deletion events remain outside the verified write contract. - Broad concurrent/offline convergence has not been verified. One controlled stale-ancestor test returned HTTP 409 and left no second event.
- SQLite legacy UUID remapping remains unresolved (#24); Task7 recovery does not repair that older identifier-migration problem. Orphan modification-only read records remain a separate limitation.
- CLI cache replacement uses optimistic change detection rather than a cross-process lock; use distinct
THINGS_CLI_CACHEpaths for independent concurrent consumers. - Process-kill and power-loss recovery injection has not been exercised.
Validation
Build, full race and coverage suites, vet, lint, diff checks, and independent reviews passed. Recovery tests include a real capture that restored seven missing tasks, corrected 265 date mismatches, and preserved all 5,352 audit rows byte-for-byte.
Disposable-account testing covered native and direct Task7 creation, Unicode notes, dates, completion/reopening, trash/restoration, projects/headings, tags/checklists, and batch relationships. The migrated CLI separately passed create/edit/complete/trash and corrected area/project moves against cloud, app-database, and SDK state. Recurring-template and mixed-batch refusal left the cloud head unchanged. Task7 persistence was checked through a normal app restart during the protocol investigation.
A Task6 title-only edit on an existing Task7 task and a native repeating template preserved the checked fields, including exact recurrence-rule bytes. This establishes that mixed-version case, not general recurrence-write support.
Included pull requests
- #28: request error handling and focused cleanup.
- #30: malformed CLI write prevention.
- #31: future-date scheduling.
- #32: Task7 reads and audit-preserving state recovery.
- #34: Unicode byte-offset replay and cache repair.
- #35: checked note replay and atomic failure handling.
- #36: scoped Task7 writes, recurrence preflight, and container-move correction.
Install
go get github.com/arthursoares/things-cloud-sdk@v0.6.0
go install github.com/arthursoares/things-cloud-sdk/cmd/things-cli@v0.6.0Thanks to @mckennajones for reporting the future-scheduling issue #26, addressed by PR #31.
Full changelog: v0.5.0 → v0.6.0