Files
RuDS/specs/publishing.allium

63 lines
1.8 KiB
Plaintext

-- allium: 1
-- bDS SSH Publishing
-- Distilled from: src/main/engine/PublishEngine.ts
use "./metadata.allium" as meta
entity PublishJob {
ssh_host: String
ssh_user: String
ssh_remote_path: String
ssh_mode: scp | rsync
status: pending | running | completed | failed
transitions status {
pending -> running
running -> completed
running -> failed
}
}
value UploadTarget {
kind: html | thumbnails | media
local_dir: String
remote_dir: String
}
rule UploadSite {
when: UploadSiteRequested(project, credentials)
-- Three upload targets run as parallel tasks
ensures: UploadTargetStarted(html, "html/", credentials.ssh_remote_path, credentials)
ensures: UploadTargetStarted(thumbnails, "thumbnails/", credentials.ssh_remote_path + "/thumbnails", credentials)
ensures: UploadTargetStarted(media, "media/", credentials.ssh_remote_path + "/media", credentials)
}
rule UploadViaScp {
when: UploadTargetCompleted(target, credentials)
requires: credentials.ssh_mode = scp
-- mtime-based upload detection: skip unchanged files
-- Uses SSH agent (SSH_AUTH_SOCK) for authentication
ensures: ScpUploadCompleted(target)
}
rule UploadViaRsync {
when: UploadTargetCompleted(target, credentials)
requires: credentials.ssh_mode = rsync
-- rsync --update --compress --verbose
-- Media uploads exclude .meta sidecar files
ensures: RsyncUploadCompleted(target)
@guidance
-- rsync exclude filters for .meta files on media target
}
invariant MediaSidecarsExcludedFromUpload {
-- .meta sidecar files are never uploaded to the remote server
-- They are project metadata, not public content
}
invariant SshAgentAuth {
-- Publishing uses SSH_AUTH_SOCK for key-based authentication
-- No password prompts, no interactive auth
}