Attachments

Work with attachment metadata, versioning, and provider differences.

Attachment Versioning

imdone-cli handles attachment modifications safely to avoid permission errors when working with files created by other team members.

Nested attachment folders

Keep related evidence in folders such as attachments/research/notes.md and attachments/review/notes.md. Push and pull preserve the relative paths, including files with the same basename in different folders. Workbench Files shows collapsible folders so you can browse and open that evidence in place.

For nested attachments, imdone stores individual payloads under distinct provider filenames and manages a companion imdone-attachment-paths.v1.json attachment. That index lets a fresh checkout restore the original paths without the first checkout’s metadata. Keep the index with the provider attachments. Existing flat attachments retain their names and URLs; older CLI versions do not restore nested paths. Managed nested versions remain available for historical links, while your local folder shows the current version.

If an index update is interrupted or conflicts with another writer, the command reports incomplete sync and preserves recoverable payloads. Retry the story-scoped push after resolving the reported conflict. Invalid paths, reserved-name collisions, and mismatched payload contents produce an explicit error instead of overwriting another file. Empty folders and symlinks are not synchronized.

Legacy flat attachments whose names resolve to the same local path (for example, a b.pdf and a_b.pdf, or names differing only in case) are restored as separate files. Imdone adds a deterministic suffix where needed and tracks each original provider identity, so links and later modifications still refer to the right attachment. Exact-name versions remain one local file showing the current version. Explicitly mapped nested-path conflicts still report an error.

How It Works

Jira: When you modify an attachment that was created by another user:

  • A new version is uploaded (no 403 errors)
  • The other user’s old version is preserved in Jira (not deleted)
  • Older same-name versions owned by the current Jira user are cleaned up after the new upload succeeds
  • Your local filesystem only keeps the current version
  • Metadata tracks all versions for reference

GitHub: When you modify an attachment:

  • The stable branch-backed file is updated at _imdone-attachments/{issue}/plan.md
  • GitHub’s content SHA is used to detect stale writes
  • Your local file stays at ./attachments/plan.md

Multiple Versions

If multiple team members modify the same attachment:

  • Jira: Each upload creates a new version; same-name versions owned by the current Jira user are cleaned up after a successful newer upload, versions owned by other users remain visible in the Jira UI, and on pull only the most recent version is downloaded locally
  • GitHub: The stable branch path is updated with SHA protection. If another user changed the file first, GitHub rejects the stale write instead of silently overwriting it

Deleted and Renamed Attachments

Team Sync:

When you delete or rename an attachment, imdone keeps each provider’s current attachment set aligned:

When you delete an attachment locally:

rm attachments/old-doc.pdf
imdone push
  • The file is removed from your local filesystem
  • Jira: The attachment remains in Jira (no delete attempt — avoids 403 errors)
  • GitHub: The stable branch path is deleted from imdone-attachments
  • Jira deletes are added to your local ignored list so they won’t be re-downloaded on pull
  • GitHub deletes disappear from the branch current set, so team members stop pulling the old file

When you rename an attachment:

mv attachments/doc.pdf attachments/doc-v2.pdf
imdone push
  • New attachment doc-v2.pdf is uploaded
  • Jira: Old attachment doc.pdf remains in Jira and the old name is added to your ignored list
  • GitHub: Old branch path doc.pdf is deleted and the new branch path doc-v2.pdf becomes current
  • Team members pull the provider’s current attachment set

Automatic Synchronization:

When any team member runs imdone pull:

  1. Jira comments are parsed for delete/rename events where Jira needs the ignored-list workflow
  2. GitHub reads the current attachment files from the imdone-attachments branch
  3. Only current attachments are downloaded
  4. Everyone stays in sync automatically

Manual Cleanup

Old Jira versions owned by other users are not automatically deleted from Jira. This prevents:

  • Permission errors for attachments the current user cannot delete
  • Accidental data loss
  • Team conflicts over attachment ownership

To clean up old versions:

  • Jira: imdone push cleans up older same-name versions owned by the current Jira user after a successful newer upload. Manually delete older versions owned by other users from the Jira UI when needed.
  • GitHub: Current attachments are the files present under _imdone-attachments/{issue}/; rename/delete cleanup removes old stable paths automatically

Metadata Format

Attachments are tracked in attachments/.metadata.yml with a filename-keyed structure:

attachments:
  document.pdf:
    current: "12346"  # Most recent version ID
    versions:
      - id: "12346"
        filename: "document.pdf"
        size: 1500
        created: "2025-01-16T14:00:00Z"
        author:
          displayName: "User B"
          accountId: "..."
      - id: "12345"
        filename: "document.pdf"
        size: 1000
        created: "2025-01-15T10:00:00Z"
        author:
          displayName: "User A"
          accountId: "..."
ignored:
  - id: "12347"
    filename: "old-file.png"
    reason: "deleted"
    author: "user@example.com"
    timestamp: "2025-02-25T10:00:00Z"

Auto-migration: Old metadata formats are automatically migrated to the new format on first use. No data loss occurs during migration.