feat: source prompt surfaces from the Distillery at master (fail-open to in-repo copies) #485

Closed
opened 2026-08-09 05:18:30 +00:00 by igor · 0 comments
Collaborator

SPEC REVISED by the operator (2026-08-10, supersedes the original body -- if you built against the earlier "fall back to in-repo copies" design, rework to this):

igor sources its prompt surfaces from the Distillery (joshtronic/distillery) at master, live. No pins, no submodules, and no in-repo fallbacks: the fallback is the PREVIOUSLY SOURCED copy. One initial successful pull is mandatory; after that, failures are never blockers -- the last-good cache serves.

Deliverables

  1. lib/context-source.sh implementing last-good-cache sourcing:
    • Cache dir ~/.local/state/agent/context/ holding one frontmatter-stripped body per consumed skill plus a HEAD stamp (the distillery commit the cache was built from).
    • context_refresh -- called once per tick (near the self-pull): read distillery's origin/master HEAD from the existing fetched clone (~/.local/state/agent/repos/distillery, git show pattern -- never the working tree). If HEAD == cache stamp, no-op. Otherwise extract every consumed skill (list below), validate each (frontmatter present, body >= 10 lines), and ONLY if ALL are valid: write to a temp dir and atomically swap into the cache, update the stamp. If ANY is invalid or the clone is unavailable: keep the existing cache, log ONE warn per offending HEAD (stamp the bad HEAD so the warn doesn't repeat every tick).
    • context_surface <skill-name> -- echoes the cached body. Nonzero ONLY when the cache has never been seeded.
  2. Bootstrap gate: if the cache is unseeded and context_refresh cannot seed it, prompt-consuming work is BLOCKED loudly (log + the once-daily operator alert path) -- igor does not run on missing brain. bin/doctor.sh and bin/install.sh gain a check: initial context pull succeeded.
  3. Wire the consuming surfaces through context_surface: worker-contract (worker system prompt), review-directive, voice, feedback-directive, site-work-directive, sports-digest-directive, now-directive.
  4. Tests (bin/test-context-source.sh): valid skill -> body cached, frontmatter stripped exactly; HEAD unchanged -> no-op (no re-extract); one malformed skill in a new HEAD -> ENTIRE swap refused, old cache intact, single warn; clone missing -> cache serves; unseeded cache + failed refresh -> surfaces refuse with the loud path; atomicity (temp-dir swap, no partial cache observable).

Out of scope

  • Deleting the now-unconsumed in-repo copies (AGENTS.md prompt body, bin/lib/*.md) -- separate cleanup after burn-in; note bin/check-sync.sh greps AGENTS.md's OUTCOME sentinels, so that cleanup must retarget check-sync and is explicitly NOT this ticket.
  • Any distillery-side change; pins/proofs/tags; non-igor consumers.

Verification

  • make test green including the new suite.
  • Live check: seed the cache, confirm a consuming surface's prompt contains the sourced body (no --- lines); simulate a bad master (fixture) and confirm the cache holds and warns once.

Notes

  • All-or-nothing swap is deliberate: skills reference each other's rules; a half-updated brain is worse than yesterday's whole one.
  • 3am case: broken skill merged to distillery master -> swap refused, fleet keeps last-good brain, one warn line + operator visibility. Distillery down -> same. Only a NEVER-seeded install can hard-block, and only until its first successful pull.
**SPEC REVISED by the operator (2026-08-10, supersedes the original body -- if you built against the earlier "fall back to in-repo copies" design, rework to this):** igor sources its prompt surfaces from the Distillery (joshtronic/distillery) at **master**, live. No pins, no submodules, and **no in-repo fallbacks**: the fallback is the PREVIOUSLY SOURCED copy. One initial successful pull is mandatory; after that, failures are never blockers -- the last-good cache serves. ## Deliverables 1. **`lib/context-source.sh`** implementing last-good-cache sourcing: - Cache dir `~/.local/state/agent/context/` holding one frontmatter-stripped body per consumed skill plus a `HEAD` stamp (the distillery commit the cache was built from). - `context_refresh` -- called once per tick (near the self-pull): read distillery's `origin/master` HEAD from the existing fetched clone (`~/.local/state/agent/repos/distillery`, `git show` pattern -- never the working tree). If HEAD == cache stamp, no-op. Otherwise extract every consumed skill (list below), validate each (frontmatter present, body >= 10 lines), and ONLY if ALL are valid: write to a temp dir and atomically swap into the cache, update the stamp. If ANY is invalid or the clone is unavailable: keep the existing cache, log ONE warn per offending HEAD (stamp the bad HEAD so the warn doesn't repeat every tick). - `context_surface <skill-name>` -- echoes the cached body. Nonzero ONLY when the cache has never been seeded. 2. **Bootstrap gate:** if the cache is unseeded and `context_refresh` cannot seed it, prompt-consuming work is BLOCKED loudly (log + the once-daily operator alert path) -- igor does not run on missing brain. `bin/doctor.sh` and `bin/install.sh` gain a check: initial context pull succeeded. 3. **Wire the consuming surfaces** through `context_surface`: worker-contract (worker system prompt), review-directive, voice, feedback-directive, site-work-directive, sports-digest-directive, now-directive. 4. **Tests** (`bin/test-context-source.sh`): valid skill -> body cached, frontmatter stripped exactly; HEAD unchanged -> no-op (no re-extract); one malformed skill in a new HEAD -> ENTIRE swap refused, old cache intact, single warn; clone missing -> cache serves; unseeded cache + failed refresh -> surfaces refuse with the loud path; atomicity (temp-dir swap, no partial cache observable). ## Out of scope - Deleting the now-unconsumed in-repo copies (`AGENTS.md` prompt body, `bin/lib/*.md`) -- separate cleanup after burn-in; note `bin/check-sync.sh` greps AGENTS.md's OUTCOME sentinels, so that cleanup must retarget check-sync and is explicitly NOT this ticket. - Any distillery-side change; pins/proofs/tags; non-igor consumers. ## Verification - `make test` green including the new suite. - Live check: seed the cache, confirm a consuming surface's prompt contains the sourced body (no `---` lines); simulate a bad master (fixture) and confirm the cache holds and warns once. ## Notes - All-or-nothing swap is deliberate: skills reference each other's rules; a half-updated brain is worse than yesterday's whole one. - 3am case: broken skill merged to distillery master -> swap refused, fleet keeps last-good brain, one warn line + operator visibility. Distillery down -> same. Only a NEVER-seeded install can hard-block, and only until its first successful pull.
igor self-assigned this 2026-08-09 05:19:41 +00:00
igor added spent time 2026-08-09 05:35:42 +00:00
15 minutes 56 seconds
igor removed their assignment 2026-08-09 05:35:42 +00:00
igor self-assigned this 2026-08-09 05:55:22 +00:00
igor added spent time 2026-08-09 06:10:52 +00:00
15 minutes 25 seconds
igor removed their assignment 2026-08-09 06:10:53 +00:00
igor self-assigned this 2026-08-09 06:12:38 +00:00
igor added spent time 2026-08-09 06:21:24 +00:00
8 minutes 13 seconds
igor removed their assignment 2026-08-09 06:21:24 +00:00
igor closed this issue 2026-08-09 06:27:29 +00:00
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Total time spent: 39 minutes 34 seconds
igor
39 minutes 34 seconds
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
joshtronic/igor#485
No description provided.