Skip to content

Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

Description

@ineedjet

Context

Split out from #108 ("Move desired apps from vault configuration to target
configuration") — a separate, follow-on feature, not required for that core
move to land. #108 has since merged (#110), so this is now unblocked.

Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
a Capistrano-style deployment system"), closed as a duplicate of this issue.

Framing

Flightdeck is much closer to a Capistrano-style deployment system than to a
long-running scheduler/orchestrator such as Nomad or Kubernetes:

Flightdeck manages versioned deployments of containerized applications
and encrypted configuration artifacts to hosts.

The current model already looks like a release-based deployment system —
build a concrete release from versioned artifacts, place it under a release
directory, keep shared state separately, switch current to the new
release, retain previous releases for rollback/history. The release itself
is a composition of independently versioned inputs: app bundles (app_refs),
per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
#111/#115 — the machinery-bundle concept it referred to was removed
entirely once there was nothing server-side left to ship in it.)

Proposal

The target's apps mapping (app name -> that app's own env_refs, as of
#114/#115 — was a flat list when this issue was written) should be written
into the generated release/deployment manifest.

This gives each release an explicit desired app set and allows
deployment-time comparison with the previous release:

previous: [a, b, c]
desired: [a, b]
removed: [c]

Apps removed from the target configuration can then be explicitly stopped
instead of being left running as orphaned applications.

The generated manifest remains release-scoped state rather than
introducing continuous reconciliation. It should also carry other useful,
non-secret deployment metadata: manifest/schema version, release
timestamp/identifier, target identifier, and the source refs (and their
resolved tags) for app bundles and each app's vault/env bundles. It must
never contain decrypted secrets or env values.

Architectural boundary

Keep Flightdeck deployment-time oriented rather than turning it into a
continuously running reconciler:

versioned release artifacts
↓
compose release
↓
generate release manifest / desired app state
↓
compare with previous release manifest
↓
apply transition from release N to N+1
↓
stop apps removed from desired state

Avoid expanding this into continuous scheduling/reconciliation, service
placement, health-based rescheduling, service discovery, or cluster
orchestration. Those belong to systems such as Nomad/Kubernetes and would
materially change Flightdeck's scope.

Depends on

#108 (merged via #110) — apps now lives on the target, not the vault,
which is what makes a per-release desired-state manifest coherent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
      Skip to content

      Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

      Description

      @ineedjet

      Context

      Split out from #108 ("Move desired apps from vault configuration to target
      configuration") — a separate, follow-on feature, not required for that core
      move to land. #108 has since merged (#110), so this is now unblocked.

      Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
      a Capistrano-style deployment system"), closed as a duplicate of this issue.

      Framing

      Flightdeck is much closer to a Capistrano-style deployment system than to a
      long-running scheduler/orchestrator such as Nomad or Kubernetes:

      Flightdeck manages versioned deployments of containerized applications
      and encrypted configuration artifacts to hosts.

      The current model already looks like a release-based deployment system —
      build a concrete release from versioned artifacts, place it under a release
      directory, keep shared state separately, switch current to the new
      release, retain previous releases for rollback/history. The release itself
      is a composition of independently versioned inputs: app bundles (app_refs),
      per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
      metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
      #111/#115 — the machinery-bundle concept it referred to was removed
      entirely once there was nothing server-side left to ship in it.)

      Proposal

      The target's apps mapping (app name -> that app's own env_refs, as of
      #114/#115 — was a flat list when this issue was written) should be written
      into the generated release/deployment manifest.

      This gives each release an explicit desired app set and allows
      deployment-time comparison with the previous release:

      previous: [a, b, c]
      desired: [a, b]
      removed: [c]
      

      Apps removed from the target configuration can then be explicitly stopped
      instead of being left running as orphaned applications.

      The generated manifest remains release-scoped state rather than
      introducing continuous reconciliation. It should also carry other useful,
      non-secret deployment metadata: manifest/schema version, release
      timestamp/identifier, target identifier, and the source refs (and their
      resolved tags) for app bundles and each app's vault/env bundles. It must
      never contain decrypted secrets or env values.

      Architectural boundary

      Keep Flightdeck deployment-time oriented rather than turning it into a
      continuously running reconciler:

      versioned release artifacts
      ↓
      compose release
      ↓
      generate release manifest / desired app state
      ↓
      compare with previous release manifest
      ↓
      apply transition from release N to N+1
      ↓
      stop apps removed from desired state
      

      Avoid expanding this into continuous scheduling/reconciliation, service
      placement, health-based rescheduling, service discovery, or cluster
      orchestration. Those belong to systems such as Nomad/Kubernetes and would
      materially change Flightdeck's scope.

      Depends on

      #108 (merged via #110) — apps now lives on the target, not the vault,
      which is what makes a per-release desired-state manifest coherent.

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        No labels
        No labels

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
          Skip to content

          Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

          Description

          @ineedjet

          Context

          Split out from #108 ("Move desired apps from vault configuration to target
          configuration") — a separate, follow-on feature, not required for that core
          move to land. #108 has since merged (#110), so this is now unblocked.

          Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
          a Capistrano-style deployment system"), closed as a duplicate of this issue.

          Framing

          Flightdeck is much closer to a Capistrano-style deployment system than to a
          long-running scheduler/orchestrator such as Nomad or Kubernetes:

          Flightdeck manages versioned deployments of containerized applications
          and encrypted configuration artifacts to hosts.

          The current model already looks like a release-based deployment system —
          build a concrete release from versioned artifacts, place it under a release
          directory, keep shared state separately, switch current to the new
          release, retain previous releases for rollback/history. The release itself
          is a composition of independently versioned inputs: app bundles (app_refs),
          per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
          metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
          #111/#115 — the machinery-bundle concept it referred to was removed
          entirely once there was nothing server-side left to ship in it.)

          Proposal

          The target's apps mapping (app name -> that app's own env_refs, as of
          #114/#115 — was a flat list when this issue was written) should be written
          into the generated release/deployment manifest.

          This gives each release an explicit desired app set and allows
          deployment-time comparison with the previous release:

          previous: [a, b, c]
          desired: [a, b]
          removed: [c]
          

          Apps removed from the target configuration can then be explicitly stopped
          instead of being left running as orphaned applications.

          The generated manifest remains release-scoped state rather than
          introducing continuous reconciliation. It should also carry other useful,
          non-secret deployment metadata: manifest/schema version, release
          timestamp/identifier, target identifier, and the source refs (and their
          resolved tags) for app bundles and each app's vault/env bundles. It must
          never contain decrypted secrets or env values.

          Architectural boundary

          Keep Flightdeck deployment-time oriented rather than turning it into a
          continuously running reconciler:

          versioned release artifacts
          ↓
          compose release
          ↓
          generate release manifest / desired app state
          ↓
          compare with previous release manifest
          ↓
          apply transition from release N to N+1
          ↓
          stop apps removed from desired state
          

          Avoid expanding this into continuous scheduling/reconciliation, service
          placement, health-based rescheduling, service discovery, or cluster
          orchestration. Those belong to systems such as Nomad/Kubernetes and would
          materially change Flightdeck's scope.

          Depends on

          #108 (merged via #110) — apps now lives on the target, not the vault,
          which is what makes a per-release desired-state manifest coherent.

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            No labels
            No labels

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
              Skip to content

              Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

              Description

              @ineedjet

              Context

              Split out from #108 ("Move desired apps from vault configuration to target
              configuration") — a separate, follow-on feature, not required for that core
              move to land. #108 has since merged (#110), so this is now unblocked.

              Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
              a Capistrano-style deployment system"), closed as a duplicate of this issue.

              Framing

              Flightdeck is much closer to a Capistrano-style deployment system than to a
              long-running scheduler/orchestrator such as Nomad or Kubernetes:

              Flightdeck manages versioned deployments of containerized applications
              and encrypted configuration artifacts to hosts.

              The current model already looks like a release-based deployment system —
              build a concrete release from versioned artifacts, place it under a release
              directory, keep shared state separately, switch current to the new
              release, retain previous releases for rollback/history. The release itself
              is a composition of independently versioned inputs: app bundles (app_refs),
              per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
              metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
              #111/#115 — the machinery-bundle concept it referred to was removed
              entirely once there was nothing server-side left to ship in it.)

              Proposal

              The target's apps mapping (app name -> that app's own env_refs, as of
              #114/#115 — was a flat list when this issue was written) should be written
              into the generated release/deployment manifest.

              This gives each release an explicit desired app set and allows
              deployment-time comparison with the previous release:

              previous: [a, b, c]
              desired: [a, b]
              removed: [c]
              

              Apps removed from the target configuration can then be explicitly stopped
              instead of being left running as orphaned applications.

              The generated manifest remains release-scoped state rather than
              introducing continuous reconciliation. It should also carry other useful,
              non-secret deployment metadata: manifest/schema version, release
              timestamp/identifier, target identifier, and the source refs (and their
              resolved tags) for app bundles and each app's vault/env bundles. It must
              never contain decrypted secrets or env values.

              Architectural boundary

              Keep Flightdeck deployment-time oriented rather than turning it into a
              continuously running reconciler:

              versioned release artifacts
              ↓
              compose release
              ↓
              generate release manifest / desired app state
              ↓
              compare with previous release manifest
              ↓
              apply transition from release N to N+1
              ↓
              stop apps removed from desired state
              

              Avoid expanding this into continuous scheduling/reconciliation, service
              placement, health-based rescheduling, service discovery, or cluster
              orchestration. Those belong to systems such as Nomad/Kubernetes and would
              materially change Flightdeck's scope.

              Depends on

              #108 (merged via #110) — apps now lives on the target, not the vault,
              which is what makes a per-release desired-state manifest coherent.

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                No labels
                No labels

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
                  Skip to content

                  Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

                  Description

                  @ineedjet

                  Context

                  Split out from #108 ("Move desired apps from vault configuration to target
                  configuration") — a separate, follow-on feature, not required for that core
                  move to land. #108 has since merged (#110), so this is now unblocked.

                  Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
                  a Capistrano-style deployment system"), closed as a duplicate of this issue.

                  Framing

                  Flightdeck is much closer to a Capistrano-style deployment system than to a
                  long-running scheduler/orchestrator such as Nomad or Kubernetes:

                  Flightdeck manages versioned deployments of containerized applications
                  and encrypted configuration artifacts to hosts.

                  The current model already looks like a release-based deployment system —
                  build a concrete release from versioned artifacts, place it under a release
                  directory, keep shared state separately, switch current to the new
                  release, retain previous releases for rollback/history. The release itself
                  is a composition of independently versioned inputs: app bundles (app_refs),
                  per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
                  metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
                  #111/#115 — the machinery-bundle concept it referred to was removed
                  entirely once there was nothing server-side left to ship in it.)

                  Proposal

                  The target's apps mapping (app name -> that app's own env_refs, as of
                  #114/#115 — was a flat list when this issue was written) should be written
                  into the generated release/deployment manifest.

                  This gives each release an explicit desired app set and allows
                  deployment-time comparison with the previous release:

                  previous: [a, b, c]
                  desired: [a, b]
                  removed: [c]
                  

                  Apps removed from the target configuration can then be explicitly stopped
                  instead of being left running as orphaned applications.

                  The generated manifest remains release-scoped state rather than
                  introducing continuous reconciliation. It should also carry other useful,
                  non-secret deployment metadata: manifest/schema version, release
                  timestamp/identifier, target identifier, and the source refs (and their
                  resolved tags) for app bundles and each app's vault/env bundles. It must
                  never contain decrypted secrets or env values.

                  Architectural boundary

                  Keep Flightdeck deployment-time oriented rather than turning it into a
                  continuously running reconciler:

                  versioned release artifacts
                  ↓
                  compose release
                  ↓
                  generate release manifest / desired app state
                  ↓
                  compare with previous release manifest
                  ↓
                  apply transition from release N to N+1
                  ↓
                  stop apps removed from desired state
                  

                  Avoid expanding this into continuous scheduling/reconciliation, service
                  placement, health-based rescheduling, service discovery, or cluster
                  orchestration. Those belong to systems such as Nomad/Kubernetes and would
                  materially change Flightdeck's scope.

                  Depends on

                  #108 (merged via #110) — apps now lives on the target, not the vault,
                  which is what makes a per-release desired-state manifest coherent.

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    No labels
                    No labels

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
                      Skip to content

                      Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

                      Description

                      @ineedjet

                      Context

                      Split out from #108 ("Move desired apps from vault configuration to target
                      configuration") — a separate, follow-on feature, not required for that core
                      move to land. #108 has since merged (#110), so this is now unblocked.

                      Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
                      a Capistrano-style deployment system"), closed as a duplicate of this issue.

                      Framing

                      Flightdeck is much closer to a Capistrano-style deployment system than to a
                      long-running scheduler/orchestrator such as Nomad or Kubernetes:

                      Flightdeck manages versioned deployments of containerized applications
                      and encrypted configuration artifacts to hosts.

                      The current model already looks like a release-based deployment system —
                      build a concrete release from versioned artifacts, place it under a release
                      directory, keep shared state separately, switch current to the new
                      release, retain previous releases for rollback/history. The release itself
                      is a composition of independently versioned inputs: app bundles (app_refs),
                      per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
                      metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
                      #111/#115 — the machinery-bundle concept it referred to was removed
                      entirely once there was nothing server-side left to ship in it.)

                      Proposal

                      The target's apps mapping (app name -> that app's own env_refs, as of
                      #114/#115 — was a flat list when this issue was written) should be written
                      into the generated release/deployment manifest.

                      This gives each release an explicit desired app set and allows
                      deployment-time comparison with the previous release:

                      previous: [a, b, c]
                      desired: [a, b]
                      removed: [c]
                      

                      Apps removed from the target configuration can then be explicitly stopped
                      instead of being left running as orphaned applications.

                      The generated manifest remains release-scoped state rather than
                      introducing continuous reconciliation. It should also carry other useful,
                      non-secret deployment metadata: manifest/schema version, release
                      timestamp/identifier, target identifier, and the source refs (and their
                      resolved tags) for app bundles and each app's vault/env bundles. It must
                      never contain decrypted secrets or env values.

                      Architectural boundary

                      Keep Flightdeck deployment-time oriented rather than turning it into a
                      continuously running reconciler:

                      versioned release artifacts
                      ↓
                      compose release
                      ↓
                      generate release manifest / desired app state
                      ↓
                      compare with previous release manifest
                      ↓
                      apply transition from release N to N+1
                      ↓
                      stop apps removed from desired state
                      

                      Avoid expanding this into continuous scheduling/reconciliation, service
                      placement, health-based rescheduling, service discovery, or cluster
                      orchestration. Those belong to systems such as Nomad/Kubernetes and would
                      materially change Flightdeck's scope.

                      Depends on

                      #108 (merged via #110) — apps now lives on the target, not the vault,
                      which is what makes a per-release desired-state manifest coherent.

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        No labels
                        No labels

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
                          Skip to content

                          Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

                          Description

                          @ineedjet

                          Context

                          Split out from #108 ("Move desired apps from vault configuration to target
                          configuration") — a separate, follow-on feature, not required for that core
                          move to land. #108 has since merged (#110), so this is now unblocked.

                          Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
                          a Capistrano-style deployment system"), closed as a duplicate of this issue.

                          Framing

                          Flightdeck is much closer to a Capistrano-style deployment system than to a
                          long-running scheduler/orchestrator such as Nomad or Kubernetes:

                          Flightdeck manages versioned deployments of containerized applications
                          and encrypted configuration artifacts to hosts.

                          The current model already looks like a release-based deployment system —
                          build a concrete release from versioned artifacts, place it under a release
                          directory, keep shared state separately, switch current to the new
                          release, retain previous releases for rollback/history. The release itself
                          is a composition of independently versioned inputs: app bundles (app_refs),
                          per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
                          metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
                          #111/#115 — the machinery-bundle concept it referred to was removed
                          entirely once there was nothing server-side left to ship in it.)

                          Proposal

                          The target's apps mapping (app name -> that app's own env_refs, as of
                          #114/#115 — was a flat list when this issue was written) should be written
                          into the generated release/deployment manifest.

                          This gives each release an explicit desired app set and allows
                          deployment-time comparison with the previous release:

                          previous: [a, b, c]
                          desired: [a, b]
                          removed: [c]
                          

                          Apps removed from the target configuration can then be explicitly stopped
                          instead of being left running as orphaned applications.

                          The generated manifest remains release-scoped state rather than
                          introducing continuous reconciliation. It should also carry other useful,
                          non-secret deployment metadata: manifest/schema version, release
                          timestamp/identifier, target identifier, and the source refs (and their
                          resolved tags) for app bundles and each app's vault/env bundles. It must
                          never contain decrypted secrets or env values.

                          Architectural boundary

                          Keep Flightdeck deployment-time oriented rather than turning it into a
                          continuously running reconciler:

                          versioned release artifacts
                          ↓
                          compose release
                          ↓
                          generate release manifest / desired app state
                          ↓
                          compare with previous release manifest
                          ↓
                          apply transition from release N to N+1
                          ↓
                          stop apps removed from desired state
                          

                          Avoid expanding this into continuous scheduling/reconciliation, service
                          placement, health-based rescheduling, service discovery, or cluster
                          orchestration. Those belong to systems such as Nomad/Kubernetes and would
                          materially change Flightdeck's scope.

                          Depends on

                          #108 (merged via #110) — apps now lives on the target, not the vault,
                          which is what makes a per-release desired-state manifest coherent.

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            No labels
                            No labels

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps · Issue #109 · rubykatzen/flightdeck · GitHub
                              Skip to content

                              Track desired app set in the deployment manifest, diff against previous release to stop orphaned apps #109

                              Description

                              @ineedjet

                              Context

                              Split out from #108 ("Move desired apps from vault configuration to target
                              configuration") — a separate, follow-on feature, not required for that core
                              move to land. #108 has since merged (#110), so this is now unblocked.

                              Folds in the framing and scope guardrails from #107 ("Define Flightdeck as
                              a Capistrano-style deployment system"), closed as a duplicate of this issue.

                              Framing

                              Flightdeck is much closer to a Capistrano-style deployment system than to a
                              long-running scheduler/orchestrator such as Nomad or Kubernetes:

                              Flightdeck manages versioned deployments of containerized applications
                              and encrypted configuration artifacts to hosts.

                              The current model already looks like a release-based deployment system —
                              build a concrete release from versioned artifacts, place it under a release
                              directory, keep shared state separately, switch current to the new
                              release, retain previous releases for rollback/history. The release itself
                              is a composition of independently versioned inputs: app bundles (app_refs),
                              per-app vault/env bundles (apps.<name>.env_refs), and generated deployment
                              metadata. (Update: there's no separate "Flightdeck bundle" anymore as of
                              #111/#115 — the machinery-bundle concept it referred to was removed
                              entirely once there was nothing server-side left to ship in it.)

                              Proposal

                              The target's apps mapping (app name -> that app's own env_refs, as of
                              #114/#115 — was a flat list when this issue was written) should be written
                              into the generated release/deployment manifest.

                              This gives each release an explicit desired app set and allows
                              deployment-time comparison with the previous release:

                              previous: [a, b, c]
                              desired: [a, b]
                              removed: [c]
                              

                              Apps removed from the target configuration can then be explicitly stopped
                              instead of being left running as orphaned applications.

                              The generated manifest remains release-scoped state rather than
                              introducing continuous reconciliation. It should also carry other useful,
                              non-secret deployment metadata: manifest/schema version, release
                              timestamp/identifier, target identifier, and the source refs (and their
                              resolved tags) for app bundles and each app's vault/env bundles. It must
                              never contain decrypted secrets or env values.

                              Architectural boundary

                              Keep Flightdeck deployment-time oriented rather than turning it into a
                              continuously running reconciler:

                              versioned release artifacts
                              ↓
                              compose release
                              ↓
                              generate release manifest / desired app state
                              ↓
                              compare with previous release manifest
                              ↓
                              apply transition from release N to N+1
                              ↓
                              stop apps removed from desired state
                              

                              Avoid expanding this into continuous scheduling/reconciliation, service
                              placement, health-based rescheduling, service discovery, or cluster
                              orchestration. Those belong to systems such as Nomad/Kubernetes and would
                              materially change Flightdeck's scope.

                              Depends on

                              #108 (merged via #110) — apps now lives on the target, not the vault,
                              which is what makes a per-release desired-state manifest coherent.

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                No labels
                                No labels

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions