Side B adds a clean, self-contained CI/CD workflow that provides lasting automation value with no downsides. Side A is a small UI tweak/simplification but also removes a pin-form feature and a vote preview block without clear explanation, mixing minor cleanup with functionality removal, making its net lasting value less clear-cut.
constitution · epochs · watch · epoch 3
c_7074f7a7bb57 (tommy-mor) vs c_5c85fe45df61 (tommy-mor)
download prompt · raw event · cmp_b259e6640fcd97
council reasoning
B adds a durable CI deploy workflow (checkout, flyctl setup, remote deploy on main) that keeps production in sync without manual steps. A mostly removes pin UI/RPC and a vote-preview block plus a one-line display:flex tweak, so its lasting product/infra impact is smaller and partly subtractive.
Side B adds a GitHub Actions workflow that automatically deploys the Fly.io application on pushes to main, including concurrency control and authenticated deployment, creating an ongoing operational improvement for the project. Side A mostly removes UI elements (pin form and vote preview), drops an unused parameter, and adds a missing `display: flex` CSS rule; while it includes minor cleanup and a small styling fix, it is a narrower, less broadly impactful change.
sides
A — c_7074f7a7bb57 (tommy-mor)
message
[f7eb8b76] css
diff preview
diff --git a/server/src/html/garden.rs b/server/src/html/garden.rs
index 41f9e9c64a80a55a9d3ece2a6a1f592cf5e8d8dd..8fc6be1de8dd975f9547de615809222236be4b70 100644
--- a/server/src/html/garden.rs
+++ b/server/src/html/garden.rs
@@ -362,7 +362,6 @@ fn child_row_pin_or_vote(
row_item: &ItemId,
pinned_room_and_item: Option<&(String, ItemId)>,
scope_content: &ContentState,
- next_path: &str,
) -> maud::Markup {
let pin_matches_scope = pinned_room_and_item
.map(|(r, _)| r == nav.room_wire.as_str())
@@ -371,21 +370,9 @@ fn child_row_pin_or_vote(
.filter(|_| pin_matches_scope)
.map(|(_, i)| i);
- let pin_rpc = template_json_compact(
- &json!({
- "action": "set_garden_pin",
- "clear": false,
- "room_wire": nav.room_wire.clone(),
- "item_storage": row_item.as_str(),
- "next": next_path,
- "form_action": "/ui",
- }),
- )
- .expect("child pin rpc json");
-
html! {
- span class="ont-garden-child-actions" data-garden-room=(nav.room_wire.as_str()) {
- @if let Some(pi) = pinned_item {
+ @if let Some(pi) = pinned_item {
+ span class="ont-garden-child-actions" data-garden-room=(nav.room_wire.as_str()) {
@if pi == row_item {
span class="ont-garden-pinned-here" title="Pinned" aria-label="Pinned" { "📌" }
} @else {
@@ -400,11 +387,6 @@ fn child_row_pin_or_vote(
span class="ont-garden-vote-count" { (format!("{}", nv)) }
}
}
- } @else {
- form method="POST" action="/ui" data-navigate="full" class="ont-pin-form ont-garden-pin-form" {
- input type="hidden" name=(UI_RPC_FIELD) value=(pin_rpc);
- button type="submit" class="ont-garden-pin-ico" title="Pin" aria-label="Pin" { "📌" }
- }
}
}
}
@@ -1190,7 +1172,7 @@ async fn render_scope_view(
@let item_url = item_href(r.item.as_str(), &nav);
@let score_str = format!("{:.3}", r.score);
li data-garden-item=(r.item.as_str()) {
- (child_row_pin_or_vote(&nav, &r.item, pin_ref.as_ref(), scope_content, &next_for_pin))
+ (child_row_pin_or_vote(&nav, &r.item, pin_ref.as_ref(), scope_content))
a class="item-link" href=(item_url) { code { (item_display_path(r.item.as_str())) } }
span class="ont-rank-score" { (score_str) }
}
@@ -1206,7 +1188,7 @@ async fn render_scope_view(
ul class="ont-group-list" {
@for name in &model.child_rankings.unranked_items {
li data-garden-item=(name.as_str()) {
- (child_row_pin_or_vote(&nav, name, pin_ref.as_ref(), scope_content, &next_for_pin))
+ (child_row_pin_or_vote(&nav, name, pin_ref.as_ref(), scope_content))
@let href = item_href(name.as_str(), &nav);
a class="item-link" href=(href) { code { (item_display_path(name.as_str())) } }
}
@@ -1353,10 +1335,6 @@ async fn vote_compare_inner(
div id="vote-edge-history-region" {
(edge_history)
}
- div class="vote-compare-preview-wrap" {
- h3 { "your vote (after post)" }
- div id="vote-compare-preview" class="vote-compare-preview" {}
- }
@if can_post {
form id="vote-compare-form" method="POST" action="/ui" {
input type="hidden" name=(UI_RPC_FIELD) value=(rpc_json);
diff --git a/server/static/theme_retro_craft.css b/server/static/theme_retro_craft.css
index 0871e3126c656ba534306cdc3f405f802d10b589..6eb9222184a8795d67a5d09d41de08c8ac1b148f 100644
--- a/server/static/theme_retro_craft.css
+++ b/server/static/theme_retro_craft.css
@@ -638,6 +638,7 @@ body.view-ontology .ont-item-meta {
flex-wrap: wrap;
align-items: center;
gap: 0.35rem;
+ display: flex;
}
body.view-ontology .ont-item-title {
flex: 1 1 auto;
B — c_5c85fe45df61 (tommy-mor)
message
[f9e40bb1] add github actions workflow to deploy fly app on main Run flyctl deploy remotely when main is updated so sorter-fly-app stays in sync without manual deploys. Co-authored-by: Cursor <cursoragent@cursor.com>
diff preview
diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3e693915fe6f99a5c2221b2921bf8ebc305180fc
--- /dev/null
+++ b/.github/workflows/fly-deploy.yml
@@ -0,0 +1,30 @@
+name: deploy to fly.io
+
+on:
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+
+concurrency:
+ group: fly-deploy-main
+ cancel-in-progress: true
+
+jobs:
+ deploy:
+ name: deploy sorter-fly-app
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ steps:
+ - name: checkout
+ uses: actions/checkout@v4
+
+ - name: setup flyctl
+ uses: superfly/flyctl-actions/setup-flyctl@master
+
+ - name: deploy
+ run: flyctl deploy --remote-only --ha=false --strategy immediate --wait-timeout 600
+ env:
+ FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
Hardlinks — judgments / attempts / prompt
judgments
attempts
Prompt text is loaded only by the download route.