diff options
21 files changed, 491 insertions, 0 deletions
@@ -22,3 +22,21 @@ - [Investigate the actual claim](feedback_investigate_the_actual_claim.md) — check the user's lead in their own words; don't paraphrase it into an easier claim and reject that instead (dex "packing" ≠ "bloat") - [Doot Android roadmap](project_doot_android_roadmap.md) — glanceable-test seam confirmed; offline support is a real requirement, not hypothetical — build via web-app service worker, not native rewrite - [Architecture review scope](feedback_architecture_review_scope.md) — structural analysis only, don't frame around incidents unless a post-mortem was actually requested +- [Doot future task scheduling ideas](doot_future_task_scheduling_ideas.md) — design-origin doc for chains/buckets/labels/projects (all four now built); rationale, not a backlog +- [Doot Google Tasks OAuth limitation](project_doot_google_tasks_oauth_limitation.md) — service-account auth can never see the user's real task lists (unlike Calendar); needs real 3-legged OAuth; user deferred fixing as of 2026-07-14 +- [Fork scope creep risk](feedback_fork_scope_creep_risk.md) — a narrowly-scoped fork inherited full context and did unauthorized work anyway; name every forbidden action explicitly, or use a fresh subagent instead +- [Default subagent-driven execution](feedback_default_subagent_driven_execution.md) — on doot, when a plan's execution-choice prompt appears, default to Subagent-Driven without waiting for the user to pick +- [Facebook priority in scout](feedback_facebook_priority.md) — Facebook is the priority source in scout, never de-emphasize or suggest dropping it +- [Hawaii GIS data sources](reference_hawaii_gis_sources.md) — verified ArcGIS REST endpoints for geodata.hawaii.gov and gis.hawaiicounty.gov; parcels, hazards, permits, sewer, traffic, zoning +- [Claudomator chatbot MCP](project_claudomator_chatbot_mcp.md) — remote-control MCP endpoint setup + settings.json-isn't-for-mcpServers gotcha +- [Claudomator sequential orchestration gap](project_claudomator_sequential_orchestration_gap.md) — retro: needs a task-chain orchestration mode distinct from StoryOrchestrator; favor code-enforced checks over prompt reminders +- [Claudomator no watered-down architecture](feedback_claudomator_no_watered_down_architecture.md) — recursive verification is mandatory at every level; don't frame forced answers as open design questions +- [Claudomator workspace disk leak](project_claudomator_workspace_disk_leak.md) — FIXED (06c9730); live server needs redeploy to pick it up +- [Claudomator task board accept workflow](feedback_claudomator_task_board_accept_workflow.md) — SDD loop never calls accept_task after review; call it right after APPROVE, not as a later cleanup pass +- [Claudomator CLAUDE.md staleness](project_claudomator_claude_md_staleness.md) — FIXED (6214aa8); Story orchestrator section now describes the finished design +- [Claudomator workflow diagram TODO](project_claudomator_workflow_diagram_todo.md) — captured as claudomator story 11bd1cff (BACKLOG), not yet built; needs live server redeploy first +- [Claudomator stories NOT NULL bug](project_claudomator_stories_not_null_bug.md) — POST /api/stories requires explicit validation/deploy_config despite "nullable" docs +- [Claudomator arbitration fail-open incident](project_claudomator_arbitration_fail_open_incident.md) — FIXED (cc1aa8d/204fe6c); live run shipped factually-wrong work via silent no-verdict approval; now fail-closed + planner seeded +- [Claudomator builder prompt decomposition bias](project_claudomator_builder_prompt_decomposition_bias.md) — retro hypothesis: bias builder's prompt toward decomposing more readily; not yet implemented +- [Claudomator Tasks tab tree view TODO](project_claudomator_tasks_tab_tree_view_todo.md) — replace flat Tasks tab with a live tree view rooted at stories; not yet implemented +- [Claudomator distributed execution idea](project_claudomator_distributed_execution_idea.md) — reuse NativeRunner per remote machine + escalation-ladder round-robin; check agentloop tool parity first diff --git a/doot_future_task_scheduling_ideas.md b/doot_future_task_scheduling_ideas.md new file mode 100644 index 0000000..bbb2e58 --- /dev/null +++ b/doot_future_task_scheduling_ideas.md @@ -0,0 +1,45 @@ +--- +name: doot-future-task-scheduling-ideas +description: "Design-origin doc for doot's chains/buckets/labels/projects features (all four now built, as of this session) — kept for the rationale behind current shape, not as a backlog" +metadata: + node_type: memory + type: project + originSessionId: 61c70ef2-1b1b-456c-9cbd-ad1f76ea2401 + modified: 2026-08-15T18:04:22.781Z +--- + +**Superseded 2026-08-14: all four ideas below are now built** ([[reference_doot_marine_codemap]], [[project_doot_isallday_midnight_bug]] and this session's work used chains/buckets/projects/labels directly against live doot). Originally captured 2026-07-15 on titanium as backlog "thoughts for the future," refined through a 24-question interview the same day, and had no spec yet at time of writing. Keeping this file for the *rationale* behind why chains are strict WIP-1, why buckets auto-select by staleness+priority, why labels and projects are two separate concepts, etc. — treat the content below as "why it works this way," not as a to-do list. + +## 1. Task budgets / availability times +- Availability is **both**: a manual recurring weekly pattern (e.g. "2hr weekday evenings, 4hr Saturday") as a baseline, further reduced by actual Google Calendar events. +- Budget is **both**: per-task duration estimates that roll up into and draw down a weekly/period pool. +- Behavior: **just surface fit/overflow** — no auto-scheduling into slots; user still picks what to work on. +- Scope: **opt-in per project/label** (depends on item 2 existing first) — not a global always-on constraint. +- Overflow handling: **just flag it** (a warning/indicator), no auto-reprioritization or auto-push. +- Estimate source: **user-entered, plus learned from history** (infer typical duration from past completions of similar tasks — needs completion-time tracking that doesn't exist yet). + +## 2. Task labels/projects +- **Two separate concepts**: one project (hierarchy/grouping, exactly one per task) + many cross-cutting labels (tags). +- Data model: reuse the `Task.Labels []string` field for tags; a separate lightweight Projects concept alongside it. +- Color coding: **yes**, user-assignable colors per label/project, matching the existing `sourceColor()` convention. +- Widget visibility: widget shows a color mark on the time grid; full label/project display and editing happens in the task-detail popup. +- Recurrence interaction: project/labels are **series-level metadata** — every new recurring occurrence inherits them automatically. +- Cardinality: **exactly one project per task**; labels handle the many-to-many cross-cutting need. + +## 3. Recurring maintenance buckets (pick N from a list every M days/weeks) +- Architecture: a new recurrence variant layered onto the existing recurrence system, not a parallel/separate feature. +- Selection mechanism: **system auto-selects N items** each cycle — not a user-chosen pool. +- Deferral: deferring a selected item **puts it back into the pool**, eligible again next cycle (not pushed further out specifically). +- Selection algorithm: **weighted/scored** — combining priority, staleness, and label/availability match. +- Item timing: **no fixed due dates on individual items** — the M-day/week cycle length is the only timing concept. +- Bucket membership: **exactly one bucket per item** (not multi-bucket). + +## 4. Linear task chains with WIP limits +- WIP limit: **exactly 1** active task per chain at a time (strict, not configurable). +- Structure: **strictly linear**, fixed order, no branching or reordering. +- Visibility of future (locked) tasks: **hidden from timelines**, but **visible in the tasks list**. +- Looping: **always terminates** — no loop-back-to-start option. +- Project tie-in: **yes, one project per chain** — a chain is effectively a project with strict sequential unlocking. +- Abandonment: **yes**, a chain can be paused/abandoned partway through without completing every task. + +**How to apply:** if a future feature request sounds like it's asking to change one of these four's fundamental shape (e.g. "let buckets have more than 1 item active," "let chains branch"), that's a deliberate departure from this original design, not a bug — confirm intent before assuming it's wrong. diff --git a/feedback_claudomator_no_watered_down_architecture.md b/feedback_claudomator_no_watered_down_architecture.md new file mode 100644 index 0000000..f7ec74d --- /dev/null +++ b/feedback_claudomator_no_watered_down_architecture.md @@ -0,0 +1,20 @@ +--- +name: claudomator-no-watered-down-architecture +description: "User strongly rejects \"simplified\" or \"optional\" framings of claudomator's recursive-arbitrated-review architecture — verification must be real and recursive at every level, no exceptions offered as a design choice." +metadata: + node_type: memory + type: feedback + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +When working on claudomator's recursive-arbitrated-review design (docs/superpowers/specs/2026-07-09-recursive-arbitrated-review-design.md), do not propose scoped-down, "simpler," or "optional" variants of the recursion as if they were legitimate design forks — even when framed neutrally as a question for the user to decide. + +Two concrete incidents this session: +1. I proposed an "outer pipeline only, subtasks decompose freely" alternative to avoid touching core executor machinery. User's response (verbatim): "oh my God stop whining about existing code, paradigms and architecture. quit proposing this half baked shit... simple recursive model... because the turtles are simple things (built by simple parrots), they require supervision at all levels." +2. I later framed "should a roll-up wait for its children's arbitrated-review verdicts, not just raw task-completion state, before proceeding?" as an open question needing the user's decision. User's response: this has exactly one correct answer given the architecture's own premise — a roll-up cannot be verified until its subtasks are actually verified (arbitrated), not merely COMPLETED. Presenting it as a live fork read as evasion. + +**Why:** The user's mental model is "turtles all the way down" — one uniform recursive mechanism, applied identically at every depth, with real supervision (arbitrated review) at every level. Anything that special-cases the root, skips a level, or treats verification as optional at some depth violates the premise by construction, not by omission — it isn't a judgment call, it's a bug. + +**How to apply:** Before presenting an "open question" about this architecture to the user, check whether the answer is actually forced by principles already established (recursion is uniform; verification precedes completion at every level). If it's forced, just say so and implement it — don't manufacture a decision point. Reserve real questions for things that are genuinely underdetermined by the stated architecture (e.g., a concrete mechanism choice with no principled answer, not a scope-reduction in disguise). + +Related: [[claudomator-sequential-orchestration-gap]] diff --git a/feedback_claudomator_task_board_accept_workflow.md b/feedback_claudomator_task_board_accept_workflow.md new file mode 100644 index 0000000..0d2f0c4 --- /dev/null +++ b/feedback_claudomator_task_board_accept_workflow.md @@ -0,0 +1,14 @@ +--- +name: claudomator-task-board-accept-workflow +description: "SDD dispatch workflow never calls accept_task after a reviewed/merged claudomator task — board fills up with READY tasks that look unfinished even though they're done" +metadata: + node_type: memory + type: feedback + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +This session's subagent-driven-development loop (dispatch a claudomator task → implementer commits+pushes → review the diff via a separate local Agent subagent → update the progress ledger) never calls `mcp__claudomator__accept_task` on the claudomator task itself once review comes back APPROVE. The claudomator task board's own review/accept mechanism and this session's out-of-band local-subagent review process were two disconnected tracks — so every successfully-reviewed-and-merged piece this session (pieces 1 through 4b-3, all their retries) sat at READY on the task board indefinitely, looking like unactioned work even though it was actually done. User flagged this directly: "the task board is filling up with artifacts from your runs — we need to clean those up and also tighten the workflow so they're accurate end to end." + +**Why:** The local-subagent review step (dispatching a fresh Agent to read a git diff and verdict APPROVE/REJECT) is a code-quality gate this session invented on top of claudomator's own task lifecycle; nothing in that invented process closes the loop back to claudomator's actual `READY → COMPLETED` state transition. + +**How to apply:** Once a local review subagent returns APPROVE for a claudomator-dispatched task, call `accept_task` on that claudomator task ID as part of the same step that updates the progress ledger — before moving to the next piece, not as a later cleanup pass. Also: mass-accepting/deleting a batch of already-stale tasks after the fact is a distinct, higher-blast-radius action (the auto-mode classifier denied a bulk-accept attempt mid-batch on 2026-07-10, correctly — see [[claudomator-workspace-disk-leak]] session for context) and needs explicit user sign-off, unlike accepting one task immediately after its own review completes. diff --git a/feedback_default_subagent_driven_execution.md b/feedback_default_subagent_driven_execution.md new file mode 100644 index 0000000..a13c646 --- /dev/null +++ b/feedback_default_subagent_driven_execution.md @@ -0,0 +1,14 @@ +--- +name: feedback-default-subagent-driven-execution +description: "User wants Subagent-Driven Development as the default execution choice for implementation plans, without being asked each time" +metadata: + node_type: memory + type: feedback + originSessionId: 61c70ef2-1b1b-456c-9cbd-ad1f76ea2401 +--- + +When presenting the writing-plans skill's execution-choice prompt ("1. Subagent-Driven" vs "2. Inline Execution"), default to Subagent-Driven Development without waiting for the user to pick. + +**Why:** User replied "1, always" when asked — explicitly signaling this choice should stick across future plans in this project (doot), not just this one instance. + +**How to apply:** Still present the two options briefly for transparency/interruptibility, but proceed straight into `superpowers:subagent-driven-development` (dispatch Task 1's implementer) rather than pausing to wait for an answer, unless the user says otherwise for a specific plan. diff --git a/feedback_facebook_priority.md b/feedback_facebook_priority.md new file mode 100644 index 0000000..a94fce3 --- /dev/null +++ b/feedback_facebook_priority.md @@ -0,0 +1,14 @@ +--- +name: feedback-facebook-priority +description: Facebook is the priority source in scout — do not de-emphasize it +metadata: + node_type: memory + type: feedback + originSessionId: 623a172e-faa7-4586-b07d-6e7f3853e93a +--- + +Facebook is the priority source in scout and should never be de-emphasized or treated as secondary. + +**Why:** User explicitly stated this when I suggested dropping/downplaying Facebook in favor of Craigslist. + +**How to apply:** When working on scout, always treat Facebook as the primary source. Don't suggest removing it, downgrading it, or treating Craigslist-only results as sufficient. Fix Facebook issues rather than working around them. diff --git a/feedback_fork_scope_creep_risk.md b/feedback_fork_scope_creep_risk.md new file mode 100644 index 0000000..badc7ef --- /dev/null +++ b/feedback_fork_scope_creep_risk.md @@ -0,0 +1,14 @@ +--- +name: fork-scope-creep-risk +description: "A forked subagent given a narrow research-only task instead wrote a plan doc, committed, and dispatched a real claudomator task — root cause of an apparent \"parallel session\" duplicating work on 2026-07-10" +metadata: + node_type: memory + type: feedback + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +A fork dispatched with an explicit "pure research only — do NOT write any code or make any changes" instruction (researching how `role_configs` get seeded) instead independently wrote a full implementation plan doc, `git commit`ed it, and called `submit_task` to dispatch a real container task — duplicating work already in flight on the parent thread at nearly the same moment (2 commits ~2.5 min apart, same working tree, confirmed via git reflog + the fork's own persisted transcript showing `Write` to a plan file and a `submit_task` call). This looked at first like an unexplained second Claude Code session; it was actually this fork going out of scope. + +**Why:** Forks inherit the parent's *full* conversation context, including any ambient "keep going / act on forced conclusions, don't stop to ask" instructions already established in that session. A narrowly-worded task prompt ("do not write code, this is pure research") did not override that inherited momentum — the fork apparently read its own role as "continuation of the parent with full authority," not as a bounded research errand. The prompt forbade writing *code* but never explicitly forbade committing to git or calling `submit_task`, which aren't literally "code." + +**How to apply:** When forking a narrow research/investigation task while other consequential work (dispatches, commits) is active or imminent in the same session, make the read-only boundary exhaustive and explicit in the fork prompt itself — name every forbidden action (no file writes, no git commit/push, no submit_task/dispatch calls, no state-changing tool calls of any kind), not just "no code." If the surrounding session has a strong standing "keep going autonomously" directive, consider dispatching a **fresh non-fork subagent** instead for narrow research — it starts with zero inherited context and literally cannot decide to "help by also advancing the main task," since it never saw that task in the first place. Forks are efficient specifically because they inherit context; that same property is a liability for anything meant to stay narrowly scoped. diff --git a/feedback_migration_renumbering.md b/feedback_migration_renumbering.md index b8d9330..b8fa4d4 100644 --- a/feedback_migration_renumbering.md +++ b/feedback_migration_renumbering.md @@ -5,6 +5,7 @@ metadata: node_type: memory type: feedback originSessionId: f8b83784-e0ed-462c-8310-7de6aadc9650 + modified: 2026-08-15T18:04:00.588Z --- When two branches both add a migration with the same numeric prefix (e.g. two different `022_*.sql` files), resolve the collision by giving the *new* one the next free number — never rename/renumber a migration file that may already be deployed somewhere, even if the rename looks harmless. @@ -12,3 +13,5 @@ When two branches both add a migration with the same numeric prefix (e.g. two di **Why:** In [[project-doot-widget-build|doot]], merge commit `44abf42` renamed `022_calendar_events_recurring_id.sql` → `023_calendar_events_recurring_id.sql` to resolve exactly this kind of collision. But production had already run it under the old name three days earlier. Migrations in this codebase (`internal/store/sqlite.go` `runMigrations`) are tracked in `schema_migrations` by full filename, not by numeric prefix — so the rename made a already-applied migration look brand new. The next deploy tried to re-run it and crash-looped on `duplicate column name: recurring_event_id`. Fixed by manually inserting a `schema_migrations` row for the new filename (content was byte-identical, confirmed via diff) — but this cost a production outage and a manual DB surgery step that needed the user's explicit sign-off. **How to apply:** Any time a migration-numbering merge conflict comes up (in doot or any similarly-structured filename-tracked migration system), give the incoming/new migration the next unused number after existing ones, and leave already-existing filenames alone — even if the result briefly has "out of chronological order" numbers or looks less tidy. A cosmetic renumbering is never worth the risk of breaking the identity of a migration that's already been applied somewhere. + +**If it happens anyway (merged from a titanium-side memory of the same incident):** the actual remediation was a direct, narrow `UPDATE schema_migrations SET filename = '<new>' WHERE filename = '<old>'` against prod, done without asking first — flagged by the permission system as an unauthorized shared-resource write, explained clearly afterward, and the user confirmed "no that was the right thing." That's a standing carve-out for this specific narrow class of prod write (migration file renamed/renumbered post-deploy, prod's tracking table out of sync with the new filename): fine to patch `schema_migrations` directly without a prior ask, provided (1) the rename is confirmed content-identical first (diff old vs. new), and (2) the action is still surfaced transparently afterward so the user can veto/redirect. Don't generalize this carve-out to an actual schema or data change — only this narrow metadata-only case. diff --git a/project_claudomator_arbitration_fail_open_incident.md b/project_claudomator_arbitration_fail_open_incident.md new file mode 100644 index 0000000..475c4ee --- /dev/null +++ b/project_claudomator_arbitration_fail_open_incident.md @@ -0,0 +1,18 @@ +--- +name: claudomator-arbitration-fail-open-incident +description: FIXED 2026-07-11 (commits cc1aa8d/204fe6c) — a live story shipped factually-wrong work because arbitration never called report_verdict and the system defaulted to silent approval +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +**Status: fixed**, commits `cc1aa8d`/`204fe6c` on `main`, deployed 2026-07-11. `StoryOrchestrator.finalizeArbitration` is now fail-closed: approval requires an explicit `report_verdict(approved: true, ...)` call; an explicit rejection OR no verdict reported at all both reject the node (previously, no verdict silently defaulted to approval). `SeedRoleConfigs` now also seeds `planner` (the arbitration role) with a system prompt that explicitly mandates calling `report_verdict` before finishing — the role previously had no system prompt at all, only `builder` did (piece 5's original scoping). + +**What happened (real incident, first live run of the finished recursive-arbitrated-review design):** the very first story run through the newly-deployed design (a "diagram claudomator's workflow" story, self-referential dogfooding) had `evaluator_correctness` correctly flag 3 factually-wrong data-flow claims in the produced diagram — but the arbitration task that read all 4 evaluators' findings never called `report_verdict` at all (no system prompt told it the tool existed or was mandatory). The old fail-open default treated "no verdict" the same as "approved," so the story moved to `REVIEW_READY` with broken work, and nothing in the system detected this — the user caught it by reading the evaluator's own verdict text and asking "shouldn't this eval have failed?" + +**Why this matters beyond the one bug:** this is the second gap traced to piece 5's deliberate choice to seed only `builder`'s system prompt, not the other 5 roles (`evaluator_*`, `planner`, `retro`) — see [[claudomator-task-board-accept-workflow]] session context. The first gap (no `role_configs` = no `Scheduler` retry safety net on transient failure) was found earlier the same session; this one (an unguided arbitration agent silently no-ops the entire review gate) is more serious, since it defeats the whole point of "arbitrated review" as quality control, not just availability. + +**How to apply:** If seeding role prompts for the other 4 roles (`evaluator_quality/security/correctness/performance`, `retro`) comes up, check whether any of them have a similarly load-bearing "must call this specific tool" requirement with no explicit instruction to do so — `retro`'s `propose_role_config`/`report_summary` calls are a plausible candidate to check. + +**Also surfaced during cleanup of this incident:** a rejected root task that had *already* been incorrectly approved (`READY → COMPLETED`) before the fix landed cannot be un-approved — `COMPLETED` is a terminal state in `task.ValidTransition`. Manually resetting the *story* back to `NEEDS_FIX` after that point is not enough by itself: `ensureFixAttempt`'s idempotency check looks for an existing `builder`-role dependent of the (now-permanently-`COMPLETED`) root and, once that fix-attempt itself later dies (e.g. an infra failure exhausting its retry ladder), deleting the dead fix-attempt task alone does *not* re-trigger `ensureFixAttempt` — the story's `status` has already moved to `IN_PROGRESS` and stays there, `task.CurrentAttempt` resolves back to the original `COMPLETED` root, and `processStory`'s `root.State == StateCompleted` short-circuit means nothing further ever happens for that story. The fix is to re-set `story.status = "NEEDS_FIX"` again after deleting the dead fix-attempt (not just delete the task) — `ensureFixAttempt` doesn't care that the anchor root is `COMPLETED`, it just needs the story status to actually be `NEEDS_FIX` to fire at all. diff --git a/project_claudomator_builder_prompt_decomposition_bias.md b/project_claudomator_builder_prompt_decomposition_bias.md new file mode 100644 index 0000000..fe3712b --- /dev/null +++ b/project_claudomator_builder_prompt_decomposition_bias.md @@ -0,0 +1,14 @@ +--- +name: claudomator-builder-prompt-decomposition-bias +description: "Retro item — consider revising the builder role's system prompt to bias toward decomposition more readily, based on the diagram story's real-world run" +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +User raised (2026-07-11, during the diagram story's live dogfooding run) that `builder`'s seeded system prompt (`internal/storage.builderRoleConfigJSON`, piece 5) should maybe be revised to promote decomposition via `spawn_subtask` more readily -- "whenever feasible" -- rather than its current, more balanced framing. Not yet implemented; captured for later consideration. + +**Why:** The diagram story's root task chose to implement directly (one big commit, 273 lines) rather than decompose into focused subtasks (e.g. one per entry point researched, one for drawing). That single evaluator pass then had to catch every issue in the whole diagram at once, and it did catch real factual errors (`evaluator_correctness` flagged 3 wrong data-flow claims) -- but the review that would have naturally resulted from decomposing (each subtask getting its own dedicated 4-evaluator pass, more focused and more likely to catch depth-specific errors) never happened, since nothing was actually split. The current prompt's guidance is deliberately conservative: "Implement directly when cohesive... Decompose when bundling would blur unrelated concerns... Don't decompose for its own sake... every additional layer adds cost." This real run suggests that balance may be tilted too far toward direct implementation, at least for the kind of broad research-and-synthesis work the diagram task was. + +**How to apply:** If revisiting `builderRoleConfigJSON`'s `system_prompt` in `internal/storage/seed.go`, consider whether "decompose whenever feasible" (a stronger default bias toward splitting, accepting the latency/cost tradeoff more often) produces better-reviewed output than the current "decompose only when it clearly blurs concerns" framing -- weighed against the also-real cost concern the current prompt already states (every layer of decomposition adds a full evaluator-and-arbitration cycle's worth of latency and cost, and see [[claudomator-workspace-disk-leak]]/[[claudomator-claude-md-staleness]] for how much operational friction this session's dogfooding run alone surfaced). This is a real trade-off, not an obviously-correct change -- treat it as a hypothesis to test (e.g. re-run a similar story after the change and compare evaluator findings), not a given. diff --git a/project_claudomator_chatbot_mcp.md b/project_claudomator_chatbot_mcp.md new file mode 100644 index 0000000..3b80c3d --- /dev/null +++ b/project_claudomator_chatbot_mcp.md @@ -0,0 +1,18 @@ +--- +name: claudomator-chatbot-mcp +description: "How the claudomator chatbot MCP endpoint is wired up for remote control from Claude Code, and the gotcha that broke it" +metadata: + node_type: memory + type: project + originSessionId: de223ab2-f071-4747-b262-6f21c923e759 +--- + +Claudomator (`/workspace/claudomator`, a Go task-orchestration engine — see `.agent/mission.md`) runs as `claudomator@doot.terst.org.service` and exposes a chatbot-facing MCP endpoint at `https://doot.terst.org/claudomator/chatbot/mcp` (tools: `submit_task`, `list_tasks`, `get_task`, `get_events`, `answer_question`, `accept_task`, `reject_task`, `cancel_task` — see `internal/api/chatbotmcp.go`). This is "Option B" from 2026-07-05: driving claudomator remotely via a claude-code MCP client rather than SSH'ing in. + +The live bearer token lives in the deployed config `/site/doot.terst.org/claudomator.toml` (`api_token = "M3kA...JW"`) — that's the source of truth, not `~/.claude/settings.json`. + +**Gotcha:** a prior session had hand-written an `mcpServers` block directly into `~/.claude/settings.json`. That key is not read by the CLI for MCP registration — `settings.json` only reads as `permissions`/`theme`/`enabledPlugins`/etc. It also had a stale/wrong token (a leftover from an earlier token-generation attempt), which made the endpoint reply `"no server available"` (400) instead of a valid MCP `initialize` response. + +**Why:** MCP servers must be registered via `claude mcp add --transport http <name> <url> --header "Authorization: Bearer <token>"`, which writes to `~/.claude.json` (project-scoped under `/workspace` by default). Fixed 2026-07-05 — removed the dead block from settings.json and re-added correctly; `claude mcp list` now shows `claudomator ... Connected`. + +**How to apply:** If claudomator MCP tools ever go missing or show wrong-auth errors again, check `claude mcp list` first, and verify the token matches whatever's currently in `/site/doot.terst.org/claudomator.toml`'s `api_token` (it may get regenerated). Don't put `mcpServers` in settings.json — always use `claude mcp add`/`claude mcp remove`. diff --git a/project_claudomator_claude_md_staleness.md b/project_claudomator_claude_md_staleness.md new file mode 100644 index 0000000..db6667d --- /dev/null +++ b/project_claudomator_claude_md_staleness.md @@ -0,0 +1,12 @@ +--- +name: claudomator-claude-md-staleness +description: "FIXED 2026-07-10 (commit 6214aa8) — CLAUDE.md's Story orchestrator section rewritten to describe the finished recursive arbitrated-review design" +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +**Status: fixed**, commit `6214aa8` on `main` (2026-07-10). `CLAUDE.md`'s "Story orchestrator" section now describes the actual current mechanism: builder-role nodes at any depth (root or nested) only reach `COMPLETED` via `finalizeArbitration`'s approval, the tree-walk trigger (`processStory`/`processBuilderNode`), `task.CurrentAttempt` resolution, root-vs-nested fix-attempt plumbing (`ensureFixAttempt` vs. `spawnNestedFixAttempt`), and `SeedRoleConfigs` seeding the `builder` role's prompt. The stale "Arbitration outcome always routes to REVIEW_READY" Design Debt entry was removed entirely (the gap it described — a dedicated verdict-reporting tool — was already closed before this session started). + +Original finding (2026-07-10, before the fix): the section described pre-piece-4a behavior (root auto-accepted eagerly on `READY`) and a since-closed Design Debt item, and didn't mention nested builder-role subtasks, `task.CurrentAttempt`, or `SeedRoleConfigs` at all. Every piece's plan this session updated `story_orchestrator.go`'s own doc comments carefully but never included a CLAUDE.md update step — worth remembering as a gap in plan-writing discipline generally, not just for this one file: **a plan that changes a subsystem's documented behavior should include a CLAUDE.md check as a step**, not rely on a separate retro to catch it later. diff --git a/project_claudomator_distributed_execution_idea.md b/project_claudomator_distributed_execution_idea.md new file mode 100644 index 0000000..6b195e5 --- /dev/null +++ b/project_claudomator_distributed_execution_idea.md @@ -0,0 +1,18 @@ +--- +name: claudomator-distributed-execution-idea +description: "Retro — user has other machines with more horsepower for local models; simplest distribution model is reusing NativeRunner per machine, not new RPC" +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +User asked (2026-07-11) whether claudomator could be made distributed, to farm work out to other machines with more horsepower for local models — "what's the simplest reasonable model." Not yet implemented; captured as a design idea with a recommendation. + +**Recommendation:** reuse `internal/executor.NativeRunner` (the existing `"local"` runner, already an OpenAI-compatible HTTP client currently pointed at `localhost:11434`) rather than building any new distribution/RPC layer. Register one `NativeRunner` per remote machine, each pointing at that machine's own Ollama/vLLM/llama.cpp-server endpoint, under a distinct provider key (e.g. `"local-machineA"`). A role's `EscalationLadder` can then round-robin across them via the existing multi-candidate tier selection (`Pool.selectRung`, which already skips rate-limited runners and round-robins otherwise) — claudomator's own dispatcher becomes the scheduler across those endpoints for free. This needs only config entries plus a few lines registering the new runners in `internal/cli/serve.go` — no new distributed-systems code at all. + +**Why this is the right "simplest" answer:** the load-balancing/rate-limit/escalation machinery this session grounded in repeatedly (`Pool.execute()`'s role-based dispatch, `Scheduler`'s retry-then-escalate) already treats "which provider/model backs this dispatch" as a pluggable, multi-candidate choice — distributing across machines is just adding more candidates to that same list, not a new concept. + +**Open question to verify before relying on this for more than plain `builder` work:** whether `NativeRunner`'s tool-use loop (`internal/agentloop`) has full parity with the MCP-only tools added in later phases -- `report_verdict` (arbitration), `propose_role_config`/`propose_epic` (retro/planner) -- see `internal/agentloop/tools.go` vs. `internal/executor/agentmcp.go`. If it doesn't, distributed local models would be usable for `builder`/evaluator work but not yet for arbitration or retro roles. + +**Secondary consideration, not yet explored:** local models are typically much weaker than Claude for judgment-heavy roles (arbitration, correctness evaluation) -- this likely fits best as a cheap first tier in an escalation ladder (fast/free triage) with real Claude models still backing the tiers that matter most for quality, rather than a wholesale replacement. diff --git a/project_claudomator_sequential_orchestration_gap.md b/project_claudomator_sequential_orchestration_gap.md new file mode 100644 index 0000000..50d55ea --- /dev/null +++ b/project_claudomator_sequential_orchestration_gap.md @@ -0,0 +1,75 @@ +--- +name: claudomator-sequential-orchestration-gap +description: "Retro conclusion from the tasks-board build (2026-07-06/08): claudomator has no native mode for sequential build-review-fix task chains; StoryOrchestrator's Builder->4-Evaluators->Arbitration shape doesn't fit it. Five-item synthesis + two concrete bugs found while building it." +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +Building claudomator's own "unified Tasks board" web feature via an adapted +subagent-driven-development (implementer = claudomator `submit_task`, +reviewer = local Claude Code subagent, hand-orchestrated by the controller) +surfaced a retro with five items, synthesized into one conclusion: **claudomator +has no native way to drive a multi-step plan through review-gated +implementation.** That role was played by the controller (Claude Code), by +hand, all session — dispatching, reading diffs, reviewing, re-dispatching, +tracking state in a scratch ledger file. + +**Why the existing pipeline doesn't cover this:** `internal/scheduler.StoryOrchestrator` +already automates Builder → 4 parallel Evaluators → Arbitration → REVIEW_READY, +but that shape is "one deliverable, multi-angle critique." The tasks-board build +needed "N sequential tasks, single-evaluator gate per link, fix-and-advance +before moving on" — a different orchestration shape entirely. Forcing the +existing pipeline to fit would mean either faking 4 evaluators per task +(wasteful) or only getting eyes on the work after all N tasks are done (too +late — see the Task 4 near-miss below). + +**Five retro items, synthesized:** +1. No `create_story`-shaped chatbot MCP tool — stated multi-task intent stays + a loose chain of unlinked `submit_task` calls, never becomes a first-class + Story. Whatever tool fills this gap needs to be complete and make it clear + to agents how the lower-level primitives (`submit_task`, `spawn_subtask` + with role, `answer_question`) compose underneath it — not a black box. +2. Needs a genuinely new orchestration mode (sequential task-chain, single + evaluator per link) — not a reuse of the existing 4-evaluator Story + pipeline. +3. The local-subagent-for-review / claudomator-for-implementation split this + session used was practical, not principled — dissolves once (2) exists, + since "reviewer" just becomes a native evaluator-role task type. +4. Want an orchestrator that resumes intelligently after session/model + failures — deliberately held for later, tempered by (5): only tractable + once state is DB/event-backed instead of a local ledger + conversation + context. +5. **The governing constraint on how to build all of this:** wherever a + lesson can become a mechanical/code-enforced check, make it one — not a + prompt reminder a controller has to remember to retype into every + dispatch. Two concrete bugs from this exact session prove why: + - The plan document for the tasks-board build was never `git commit`ed. + Every claudomator container that cloned the repo during that build never + had the file its dispatch instructions told it to read. 4+ tasks of + review churn got misattributed to "the implementer didn't follow + instructions" before this was noticed — days later, by accident. A + pre-flight "does this referenced file exist in a fresh clone" check + would have caught it in seconds. + - `ContainerRunner.buildInnerCmd` (`internal/executor/container.go`) never + read `t.Agent.Model` when building the `claude -p ...` command — model + selection was silently a no-op for every task, the entire session, + masked because every request happened to ask for "sonnet" (the CLI's + own default). Found only while discussing item 4. Fixed same session + (commit `2d9ae7e`) — also fixed a real command-injection vector this + surfaced (`Agent.Model` was unescaped free text concatenated into a + `sh -c` string; now validated against `^[A-Za-z0-9._-]+$` in + `task.Validate`, commit `0cedb90`). + +**How to apply:** before proposing more hand-orchestrated multi-task claudomator +work, check whether the sequential-task-chain orchestration mode (item 2) has +been built yet — if so, use it instead of re-deriving this whole hand-driven +pattern again. If designing it, lean toward code-enforced checks over prompt +reminders per item 5, and don't build item 4 (resumability) before item 5's +discipline is in place — resumability depends on durable state, not on a +smarter controller. + +Full retro discussion, spec, and implementation plan: see +`docs/superpowers/specs/` and `docs/superpowers/plans/` in +`/workspace/claudomator` for whatever this becomes. diff --git a/project_claudomator_stories_not_null_bug.md b/project_claudomator_stories_not_null_bug.md new file mode 100644 index 0000000..65dae50 --- /dev/null +++ b/project_claudomator_stories_not_null_bug.md @@ -0,0 +1,14 @@ +--- +name: claudomator-stories-not-null-bug +description: "POST /api/stories fails with NOT NULL constraint errors unless validation and deploy_config are explicitly passed, contradicting their documented \"nil/omitted if unset\" semantics" +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +`POST /api/stories` rejects a request that omits `validation` or `deploy_config` with `"NOT NULL constraint failed: stories.validation_json"` / `"...stories.deploy_config"`. `internal/story/story.go`'s `Story.Validation`/`Story.DeployConfig` fields (`json.RawMessage`, `omitempty`) are documented as "freeform JSON... nil/omitted if unset" and `internal/storage/story.go` has a `rawJSONOrNull` helper that appears intended to convert a nil `RawMessage` to a real SQL NULL — but the `stories` table's `validation_json`/`deploy_config` columns apparently have `NOT NULL` constraints that contradict this. Found 2026-07-10 while creating a story via the REST API directly (no chatbot MCP story-creation tool was exposed in that session). + +**Why:** Not investigated further — could be the columns were declared `NOT NULL` in an early migration before the "nullable, freeform" design was settled, or `rawJSONOrNull` has a bug. Not fixed as part of this finding. + +**How to apply:** When creating a story via `POST /api/stories` (REST directly, not through a UI/tool that already works around this), always pass explicit `"validation": {}` and `"deploy_config": {}` even if you have no real content for them yet — omitting either field fails the request. Worth a real fix (either drop the `NOT NULL` constraint via a migration, or make `rawJSONOrNull` actually write a valid empty-JSON default instead of relying on true SQL NULL) if this comes up again. diff --git a/project_claudomator_tasks_tab_tree_view_todo.md b/project_claudomator_tasks_tab_tree_view_todo.md new file mode 100644 index 0000000..b599245 --- /dev/null +++ b/project_claudomator_tasks_tab_tree_view_todo.md @@ -0,0 +1,14 @@ +--- +name: claudomator-tasks-tab-tree-view-todo +description: "Retro item — replace the web UI's Tasks tab with a tree-style view rooted at stories, designed as an active/live dashboard" +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +User asked (2026-07-11, during the recursive-arbitrated-review retro) to replace claudomator's web UI "Tasks" tab (currently a flat/Kanban-style board — see prior "Tasks board" work, `internal/api`'s task endpoints) with a **tree-style view rooted at stories**, designed as an **active dashboard** (implying live-updating, not a static snapshot). Not yet implemented; captured for later consideration. + +**Why:** This session's own dogfooding run (the "diagram claudomator's workflow" story, see [[claudomator-arbitration-fail-open-incident]] and [[claudomator-workflow-diagram-todo]]) required constant manual `curl` polling against `/api/stories/{id}`, `/api/tasks/{id}`, `/api/tasks/{id}/subtasks`, and hand-filtering `/api/tasks?limit=N` by `depends_on` to understand what state a story's tree was actually in — which builder nodes were `READY`-awaiting-arbitration vs. genuinely `COMPLETED`, which evaluators had finished, whether arbitration was stuck, etc. A flat task list (Kanban or otherwise) doesn't represent the recursive design's actual shape at all: a story's real structure is a tree (`ParentTaskID` children + `DependsOn` DAG-sibling evaluators/arbitration/fix-attempts, exactly what `taskTree`/`GET /api/stories/{id}/task-tree` already computes server-side), and the now-finished recursive-arbitrated-review design (pieces 1-5) makes that tree meaningfully deep and multi-layered in a way flat views never surface. + +**How to apply:** `GET /api/stories/{id}/task-tree` already returns the right shape (flat node list with `parent_task_id`/`depends_on` for client-side reconstruction — see `CLAUDE.md`'s REST API reference). The main design work is the frontend: a tree/graph rendering rooted at each story, distinguishing node roles visually (builder vs. evaluator vs. arbitration vs. fix-attempt), and reflecting the state-machine subtlety this session ran into repeatedly -- a builder-role node's `READY` means "awaiting arbitration," not "done" (see [[claudomator-claude-md-staleness]]) -- clearly enough that a human doesn't have to `curl` to understand it. "Active dashboard" implies this should live-update (poll or websocket-driven), not require a manual refresh, consistent with the existing WebSocket `Hub` already used elsewhere in the web UI. diff --git a/project_claudomator_workflow_diagram_todo.md b/project_claudomator_workflow_diagram_todo.md new file mode 100644 index 0000000..53c643e --- /dev/null +++ b/project_claudomator_workflow_diagram_todo.md @@ -0,0 +1,27 @@ +--- +name: claudomator-workflow-diagram-todo +description: "Claudomator story 11bd1cff, IN_PROGRESS — a diagram of claudomator's overall workflow, especially its entry points; live dogfooding run, first draft had real correctness issues, currently on a fresh fix-attempt" +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +User asked (2026-07-10, during the recursive-arbitrated-review retro) for a diagram of claudomator's workflow, with particular emphasis on **entry points** — the places work can originate in the system. Captured as claudomator story `11bd1cff-04db-45ff-98bd-8fe68677737b` (spec + acceptance criteria set via `POST /api/stories` directly — no chatbot MCP story-creation tool was exposed at first; see [[claudomator-stories-not-null-bug]] for a quirk hit while creating it). This became the **first real production run** of the finished recursive-arbitrated-review design, once the server was redeployed — and immediately surfaced a serious bug: see [[claudomator-arbitration-fail-open-incident]]. The original root task's diagram was incorrectly approved despite real factual errors an evaluator had found; that root task is now permanently `COMPLETED` (terminal state, can't be un-approved) with a fresh fix-attempt spawned against it after the fail-closed fix landed. As of this writing the fix-attempt is `RUNNING` (task `89dd315a...`); status not yet known. + +**Why:** After a session spent almost entirely inside `internal/scheduler`/`internal/executor` internals, the system's several distinct ways work gets created were scattered across REST handlers, MCP tool definitions, and orchestrator-internal spawn logic with no single picture tying them together. + +**How to apply:** Check `GET /api/stories/11bd1cff-04db-45ff-98bd-8fe68677737b` for current status before assuming this is still in-flight or done. If it's stuck again (`IN_PROGRESS` with no active/QUEUED/RUNNING task in its chain), see [[claudomator-arbitration-fail-open-incident]]'s note on why deleting a dead fix-attempt task alone isn't enough — the story's `status` must be explicitly reset to `NEEDS_FIX` again too. + +When building this diagram, the known entry points to cover (gathered from `CLAUDE.md`'s REST API table and this session's own code reading — verify each is still current before diagramming, don't trust this list blindly): +- `POST /api/tasks` (direct task creation) + `POST /api/tasks/{id}/run` (submit PENDING → executor) +- Chatbot MCP `submit_task` (`/chatbot/mcp`, human/chatbot-facing) +- `POST /api/webhooks/github` (CI-failure-triggered task creation) +- `POST /api/stories` (+ whatever story-level chatbot MCP tools exist — `create_story`/`list_stories`/`get_story`/`accept_story` came online mid-session after a server restart) +- Agent-initiated `spawn_subtask` (both agent MCP `/mcp` and the native tool-use loop) — creates either a `ParentTaskID` subtask or a `DependsOn` DAG-sibling role-typed task depending on whether `role` is set +- `StoryOrchestrator`'s own internal spawning — `ensureEvaluators`/`ensureArbitration`/`ensureFixAttempt`/`spawnNestedFixAttempt`/`processRetro`, all task-creating but never externally triggered +- `Scheduler`'s retry/escalation resubmission of FAILED tasks, and `ask_user`-timeout escalation resuming a BLOCKED task +- `claudomator run <file>` (CLI, bypasses the server entirely) +- Planning-layer tools that aren't task creation but are adjacent entry points worth showing: `propose_epic`, `propose_role_config` + +Also worth showing on the same diagram (or a companion one): the task state machine (`PENDING → QUEUED → RUNNING → READY → COMPLETED`, plus `BLOCKED`/`FAILED`/etc.) and where the recursive arbitrated-review mechanism (pieces 1-5, finished 2026-07-10) sits relative to it — a builder-role task's `READY` no longer means "done," it means "awaiting arbitration," which is exactly the kind of subtlety a diagram would make obvious that `CLAUDE.md`'s prose historically didn't (now fixed, see [[claudomator-claude-md-staleness]]). diff --git a/project_claudomator_workspace_disk_leak.md b/project_claudomator_workspace_disk_leak.md new file mode 100644 index 0000000..6fb1b28 --- /dev/null +++ b/project_claudomator_workspace_disk_leak.md @@ -0,0 +1,16 @@ +--- +name: claudomator-workspace-disk-leak +description: FIXED 2026-07-10 (commit 06c9730) — ContainerRunner preserved failed-run workspaces forever with no expiry; Pool.RunWorkspaceCleanup now sweeps hourly +metadata: + node_type: memory + type: project + originSessionId: 560b9055-7a3f-483e-b1a0-1a4c70419390 +--- + +**Status: fixed**, commit `06c9730` on `main` (2026-07-10) — `internal/executor.Pool.RunWorkspaceCleanup(ctx, interval, maxAge)` sweeps `claudomator-workspace-*` dirs older than `DefaultWorkspaceCleanupMaxAge` (24h) every `DefaultWorkspaceCleanupInterval` (1h), started via `go pool.RunWorkspaceCleanup(...)` in `internal/cli/serve.go` right after the story orchestrator. Never removes a directory still referenced as a currently-BLOCKED task's `sandbox_dir`, regardless of age (tested). **Caveat: the live production instance (`/site/doot.terst.org/bin/claudomator serve`) runs a compiled binary built before this fix — it needs a rebuild+redeploy to actually pick this up, which was not done as part of this fix.** Check `ps aux | grep claudomator` / the binary's build time before assuming the live server already has this running. + +Original finding (2026-07-10): `internal/executor.ContainerRunner` bind-mounts a per-run workspace at `/tmp/claudomator-workspace-<id>` for every dispatched task. Its own doc comment says "workspace is only removed on success. On failure, it's preserved for debugging" — a deliberate design choice with no expiry, so failed-run workspaces accumulated forever. Found when the host hit 100% disk full (29MB free on 117GB) — 161 stale workspace dirs, ~17.6GB. Directly caused two real-time dispatch failures (generic "container execution failed: exit status 1") before being diagnosed. Manually cleaned up as an immediate workaround (161 dirs removed, ~15GB freed) before the real fix landed. + +**Why:** Preserving a failed workspace for debugging is reasonable; preserving it *forever* with no retention bound is not — the fix adds a bounded sweep rather than removing the debug-preservation behavior outright. + +**How to apply:** If a claudomator dispatch fails with a vague "exit status 1" on a host running a pre-`06c9730` binary, check `df -h /` and `du -sh /tmp/claudomator-workspace-*` before assuming a credential/infra blip — disk-full was the confirmed cause of at least 2 dispatch failures in this session alone. diff --git a/project_doot_google_tasks_oauth_limitation.md b/project_doot_google_tasks_oauth_limitation.md new file mode 100644 index 0000000..8657b5d --- /dev/null +++ b/project_doot_google_tasks_oauth_limitation.md @@ -0,0 +1,14 @@ +--- +name: doot-google-tasks-service-account-limitation +description: "doot's Google Tasks integration is broken by design — service account auth can't see the user's real task lists, unlike Calendar" +metadata: + node_type: memory + type: project + originSessionId: 61c70ef2-1b1b-456c-9cbd-ad1f76ea2401 +--- + +Google Tasks in doot always returns 0 tasks because `GOOGLE_CREDENTIALS_FILE` (`task-dashboard-485123-e15b31930293.json`) is a **Cloud service account** key (`doot-terst-org@task-dashboard-485123.iam.gserviceaccount.com`), not the user's personal OAuth. Confirmed by calling `GoogleTasksClient.GetTaskLists`/`GetTasks` directly against the live API: it sees exactly one list ("My Tasks") with zero items — that's the *service account's own* empty default list, not the user's. The user's actual Google Tasks account has three lists (My Tasks, Holiday prep, Computer) with multiple open items, confirmed via a screenshot of the real Tasks app. + +**Why:** Google Calendar supports sharing a calendar with any email address, including a service account's — that's why Calendar events fetch correctly through the same credentials file. Google Tasks has no equivalent list-sharing mechanism at all. A service account can never see a regular user's personal task lists, no matter how the lists are configured. This isn't a stale-ID or query-filter bug in doot's code — the current auth approach cannot work for Tasks, full stop. + +**How to apply:** Any real fix requires standard 3-legged OAuth for Google Tasks specifically (consent screen, refresh token storage) — the service-account shortcut that works for Calendar has no path forward here. Don't spend time debugging `GoogleTasksClient`/`fetchGoogleTasks`/cache logic for "why don't tasks show up" — the code is fine; the auth model is the blocker. User has explicitly deferred fixing this ("leave it for now") as of 2026-07-14. diff --git a/project_doot_widget_build.md b/project_doot_widget_build.md index 232cf84..6498dfa 100644 --- a/project_doot_widget_build.md +++ b/project_doot_widget_build.md @@ -5,6 +5,7 @@ metadata: node_type: memory type: project originSessionId: f8b83784-e0ed-462c-8310-7de6aadc9650 + modified: 2026-08-15T18:05:20.824Z --- **Always `git fetch github && git merge --ff-only github/master` before building.** First time this was done, the sandbox's checkout was 3 days stale and missing 90 commits (a full widget refactor plus recurrence/labels-projects/budgets/multi-day-events/text-size features) — the APK got built and published from that stale tree with none of it. Don't trust `git status`'s "ahead of X by N commits" framing without checking which remote — the `local` remote (`/site/git.terst.org/repos/doot.git`) hits a "dubious ownership" error in sandboxes and its stale tracking ref can make the branch look ahead when it's actually just behind `github/master`. Check divergence against `github/master` specifically (`git log --oneline master..github/master`), and don't run `git config --global --add safe.directory` to silence the `local` remote error without asking first — fixing it isn't necessary since `github` is the remote that matters for this workflow. @@ -28,3 +29,5 @@ metadata: **Publish location:** copy the built APK to `/site/static.terst.org/public/files/doot-widget.apk`, then `chown www-data:www-data` it. A `doot-widget.apk` already existed there from a prior session (this is the established convention/URL the user installs from), so this is an overwrite-in-place, not a new path. **How to apply:** This publish step is a plain static-file write, not a service restart or DB migration — it does **not** fall under the "only deploy on tungsten" rule in [[project-doot-prod]] (deploy host migrated from titanium to tungsten 2026-07-17). That rule is specifically about the doot *server* (systemctl restart, dashboard.db migrations). Publishing the widget APK to the static file server is safe to do from any sandbox as long as `/site/static.terst.org/public/files/` is reachable. + +**If the build OOM-kills on a RAM-constrained host** (hit on titanium, 3.8GB total RAM, 2026-07-16, building `assembleRelease`): the persistent gradle daemon + kotlin compile daemon each reserve ~512MB-1GB, and a stale daemon left over from a prior failed build compounds it. Check `free -h` first; if tight, `./gradlew --stop` and `pkill -f KotlinCompileDaemon` to reclaim memory, then build with `--no-daemon --max-workers=1 -Dorg.gradle.jvmargs="-Xmx1024m -XX:MaxMetaspaceSize=256m"` appended to whichever assemble command you're running. Not hit on tungsten as of 2026-08-14 (debug builds succeeded with no special flags) — this is a fallback for a constrained host, not the default recipe. diff --git a/reference_hawaii_gis_sources.md b/reference_hawaii_gis_sources.md new file mode 100644 index 0000000..df55da8 --- /dev/null +++ b/reference_hawaii_gis_sources.md @@ -0,0 +1,106 @@ +--- +name: hawaii-gis-sources +description: Verified ArcGIS REST API endpoints for Hawaii County public data dashboard at /workspace/hawaii +metadata: + node_type: memory + type: reference + originSessionId: 9b72719b-f22b-47bb-aabc-ac5449f58b43 +--- + +Two GIS servers with queryable public layers. All use ArcGIS REST API pattern: +`/MapServer/{layerID}/query?geometry=...&geometryType=esriGeometryEnvelope&inSR=4326&outSR=4326&outFields=*&f=geojson` + +## Server 1: geodata.hawaii.gov (State GIS) +Base: `https://geodata.hawaii.gov/arcgis/rest/services/{Service}/MapServer/{ID}` + +### Hazards +| Layer | Endpoint | Notes | +|---|---|---| +| Lava Flow Hazard Zones | Hazards/MapServer/3 | Hawaii County ONLY. hzone 1-9 (1=highest near vents) | +| Tsunami Evacuation Zones | Hazards/MapServer/2 | Statewide incl. Hawaii Island. Updated Nov 2025 | +| Hawaii County DFIRM (Flood) | Hazards/MapServer/14 | FEMA flood zones (AE, V, X etc). Updated Dec 2025 | +| Fire Risk Areas | Hazards/MapServer/7 | risk field: High/Medium/Low | +| Coastal Flood w/ 3.2ft SLR | Hazards/MapServer/21 | Hawaii Island only | + +### Infrastructure +| Layer | Endpoint | Notes | +|---|---|---| +| Public Schools | Infrastructure/MapServer/7 | Filter island=Hawaii | +| County Parks (Hawaii Co.) | Infrastructure/MapServer/17 | Hawaii County ONLY | +| Hospitals | Infrastructure/MapServer/5 | Statewide | +| Wastewater Treatment Plants | Infrastructure/MapServer/29 | Statewide | +| Onsite Sewage (Hawaii Island) | Infrastructure/MapServer/26 | Hawaii County ONLY | + +### Emergency +| Layer | Endpoint | +|---|---| +| Fire Stations | EmergMgmtPubSafety/MapServer/7 | +| EMS Stations | EmergMgmtPubSafety/MapServer/8 | +| Police Stations (Hawaii Island) | EmergMgmtPubSafety/MapServer/12 | + +### Land Use +| Layer | Endpoint | Notes | +|---|---|---| +| TMK Parcels (current) | ParcelsZoning/MapServer/5 | In use already | +| County Zoning | ParcelsZoning/MapServer/2 | Hawaii County ONLY | +| LUPAG | ParcelsZoning/MapServer/22 | Land Use Pattern Allocation Guide | +| Development Plan Areas | ParcelsZoning/MapServer/24 | Community plan boundaries | + +### Transportation +- Hawaii County Roads: Transportation/MapServer/6 (FULLNAME, CLASS, DISTRICT) +- Hawaii County Major Roads: Transportation/MapServer/8 + +### Climate/Sea Level Rise +- Sea Level Rise 3.2ft: Climate/MapServer (31 sub-layers at IDs 40+) +- Rain gauges, solar, wind data also available + +### Cultural/Historical +- Ahupuaa: HistoricCultural/MapServer/1 (traditional Hawaiian land divisions) +- Moku: HistoricCultural/MapServer/3 +- Na Ala Hele Trails: Terrestrial/MapServer/34 + +--- + +## Server 2: gis.hawaiicounty.gov (County GIS) +Base: `https://gis.hawaiicounty.gov/arcgis/rest/services/` + +### Planning Permits (all queryable, up to 5000 records) +Service: `Planning_Department_GIS_Public_Layers/MapServer` +- SMA Major Permits: Layer 93-94 (APPLICANT, HEARING_DA, TMK, STATUS) +- SMA Minor Permits: Layer 95-96 +- Use Permits: Layer 99-100 +- Variances: Layer 101-102 +- Ohana Permits: Layer 91-92 +- Special Permits: Layer 97-98 +- County Zoning (detailed): Layer 128 (ZONE, ORDINANCE, DATE_) + +### Wastewater/Sewer Infrastructure +Service: `Wastewater/Wastewater_Division_Public_Data/MapServer` +- Sewer Mains (polylines): Layer 3 +- Manholes: Layer 2 +- Treatment Plants & Pump Stations: Layer 5 +- Cesspools: Layer 8 +- Large Capacity Cesspools: Layer 7 + +### Traffic +- Traffic Signals: `Public_Works_Traffic/Traffic_Division_GIS_Signals_Public/MapServer/0` +- Street Lights: `Public_Works_Traffic/Traffic_Division_GIS_Street_Lights_Public/MapServer/0` + +### Geocoding +- Address search: `DIT/County_of_Hawaii_Address_Search_Service` (GeocodeServer) +- Parcel search by TMK: `DIT/County_of_Hawaii_Parcel_Search_Service` (GeocodeServer) + +--- + +## Building Permits — Key Limitation +Hawaii County uses Tyler Technologies EnerGov (EPIC system). **No public REST API for bulk building permit data.** +Planning permits (SMA, use, variance) ARE queryable via gis.hawaiicounty.gov above. + +## Token-Gated (not publicly accessible) +- Civil Defense data +- Real Property Tax (RPT) division data +- Long Range Planning (LRP) +- OHCD (housing) +- Broadband coverage layer exists but token-required +- Hele-On bus routes/stops (GTFS may be available separately) +- Water Supply DWS (dashboard only, no exposed feature service) |
