Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 136 additions & 223 deletions .dev-loop/INGEST_REPORT.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions log.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@ Append-only. Format: `## [YYYY-MM-DD] <ingest|revise|lint|gap|contradiction|drif
## [2026-08-30] revise | frontend/design/design-canvas-workflow — agent-gate Check 3 remediation (PR #164). The gate's fact finding was half right: its "no skill named `design` exists" conclusion is refuted by ground truth (the skill is listed in the authoring session's available-skills roster as `design: Create a design canvas…` and its bundled payload exists on the authoring machine's disk; the reviewer's CI environment lacks the preview, and it conflated the skill with the unrelated `/design-sync` component-upload tool) — but the verifiability objection stands: the skill is an early research preview absent from public docs, so a single un-fetchable in-session source cannot carry `confidence: verified`. Fixed per AGENTS.md: confidence downgraded to field-tested with the experience context stated in the body; two live-fetched public sources added (anthropic.com/news/claude-design-anthropic-labs — official Claude Design product announcement, research preview, Claude Code handoff; explainx.ai 2026 post — /design ships in Claude Code as a research-preview command producing editable artboards via the Artifacts runtime); the mandatory-routing directive and the frontend/index.md load-when line conditioned on the skill appearing in the session's available-skills list, with the existing no-skill edge case as the explicit fallback; the unverifiable "design-review skill" name-drop in the audit edge case generalized to session-provided audit tooling.
## [2026-09-03] ingest | databases/selection — new category: datastore selection by workload (4 pages: choosing-a-datastore-by-workload, relational-jsonb-vs-document-store, vector-search-engine-selection, graph-workloads-relational-vs-graph-db); brave-search research, sources cited per page
## [2026-09-04] ingest | infrastructure/agent-orchestration/code-graph-as-orientation-layer (field-tested — 1 new page). A locally built code knowledge graph (graphify) is a freshness-gated, lead-not-evidence orientation layer for planning and parallel task decomposition: gate on graph mtime vs git log, symbol-anchored explain/path only, CLI delivery with bounded output, graph-derived assumptions named in reports. Sources: Developers Digest, AQ Score, Autonoma, Tiare Balbi, graphify README + measurements on graphifyy 0.4.23.
## [2026-09-16] ingest | knowledge-flush of the harvested insight queue — 2 new pages, 3 amended pages, 2 domain indexes updated; 4 of 4 claimed candidates ingested, 0 dropped. New: testing/quality/precedence-between-competing-exit-conditions (verified — a test claiming one exit condition beats another must stage the competing condition to become true in the same iteration the condition under test reaches its threshold, derive that iteration from the threshold rather than a literal, prove the assertion by swapping the two source blocks and requiring exactly that test to redden, and assert the loser's side effect did not run; grounded in the mutation-testing infection condition — Vera-Pérez et al. 2019, "the test inputs are not sufficient to infect the state of the program" — plus PIT's per-test kill attribution, with the dev-loop watch-status.sh R6 precedence case as the field measurement), infrastructure/agent-orchestration/escape-hatch-uses-as-a-knowledge-gap-signal (field-tested — a grounding gate's escape hatch is the only place that knows a decision had no source, so the gate emits one gap-queue row at the point it grants the pass, with the decision text, an enumerated reason separating "no page exists" from "page exists but was not found", and a periodic reconciliation of hatch uses against queue rows; the hatch keeps passing. GitHub code scanning's dismissal flow cited as the canonical recorded-hatch shape — mandatory reason, comment on the alert timeline, `dismissed_comment` on the API, reviewable Closed list. Measured locally: plan-gate.sh:166 passes `[no-wiki]` with a bare `continue` while SKILL.md:135 asks in prose for an ingest candidate — 276 non-index pages, exactly one `gap` entry in this log). Amended: infrastructure/agent-orchestration/pane-delivery-confirmation +Do-this #6 / +1 edge row / +1 Instead-of row (skip the pane check entirely on an iteration that sent keys — the pane repaints only after the target consumes the input, so a same-iteration capture can confirm the very state the send just cleared; reproduced 2026-09-16 on tmux/macOS, where a 0.4s-working command left the same-iteration capture reading the stale witness while an instant command repainted in time, making the outcome a function of the target's work time), platforms/processes/driving-a-tui-in-a-tmux-pane +1 edge row pointing at that rule, infrastructure/agent-orchestration/code-graph-as-orientation-layer +2 edge rows and +2 sources (graphifyy 0.4.23 installs post-commit and post-checkout only, while `git pull` runs post-merge — reproduced on git 2.50.1: fast-forward pull and merge-commit pull both fired post-merge alone, a merge commit fired no post-commit, and a fresh clone carried no hooks at all — so "PR merged upstream, then pull" leaves the graph stale with hooks reporting installed; freshness gate stays mandatory, add a post-merge hook, and build from a workspace scan after a clone). Reciprocal related links added both ways (tests-that-cannot-fail, policy-at-several-return-sites, completion-predicates; session-completion-gates, autonomous-decision-rulings, spec-document-gates). Structure checks 278 pages / 13 indexes / 0 findings; no prohibition-lint findings on the touched pages.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ confidence: field-tested
sources:
- https://github.com/obra/superpowers
last_verified: 2026-08-22
related: [infrastructure-agent-orchestration-unattended-worker-questions, infrastructure-agent-orchestration-shared-run-state, infrastructure-agent-orchestration-control-signals-vs-primary-artifacts, security-agent-exposure-authorization-scope-persistence]
related: [infrastructure-agent-orchestration-unattended-worker-questions, infrastructure-agent-orchestration-shared-run-state, infrastructure-agent-orchestration-control-signals-vs-primary-artifacts, security-agent-exposure-authorization-scope-persistence, infrastructure-agent-orchestration-escape-hatch-uses-as-a-knowledge-gap-signal]
---

# Deciding Without a Human During an Unattended Run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sources:
- https://getautonoma.com/blog/parallel-ai-agent-prs
- https://www.tiarebalbi.com/en/blog/code-graphs-coding-agents-delivery-shape
- https://github.com/Graphify-Labs/graphify
last_verified: 2026-09-04
last_verified: 2026-09-16
related: [infrastructure-agent-orchestration-worktree-isolated-workers, infrastructure-agent-orchestration-session-context-token-budget, infrastructure-agent-orchestration-control-signals-vs-primary-artifacts, qa-process-completion-claims]
---

Expand All @@ -33,7 +33,8 @@ dispatch; deciding whether a graph result can stand as evidence in a plan.
artifact of "what changed". Treat a graph older than the newest code commit as
stale, and treat an unreadable graph, a missing CLI, or a non-git root as
"cannot evaluate": in all of those cases plan from the files, exactly as if no
graph existed.
graph existed. Run this check even where the tool's git hooks are installed —
the edge cases below name the update paths those hooks do not cover.

2. **Use the graph to choose where to look; use files, tests, and runtime to
decide what is true.** A graph hit is a lead, never evidence. Every affected
Expand Down Expand Up @@ -84,6 +85,8 @@ dispatch; deciding whether a graph result can stand as evidence in a plan.
| Routes, handlers, or imports are generated by framework convention, decorators, or dynamic imports | The graph under-reports edges there; widen the search with grep on the convention (route table, decorator name) before trusting a "no callers" result |
| The graph and a file disagree | The file wins; record the disagreement as a staleness incident and drop the graph for the rest of the task |
| Uncommitted edits exist in the checkout | The mtime-vs-log check does not count them; a graph is "fresh" relative to commits only — re-run the check after the edits land if the plan depends on them |
| The repository has the tool's hooks installed (`graphify hook install`) | Add a `post-merge` hook of your own and keep the freshness check: graphifyy 0.4.23 installs `post-commit` and `post-checkout` only, while `git pull` — fast-forward or merge commit — runs `post-merge`, so "PR merged upstream, then pull", the most common way main advances, leaves the graph stale while `hook status` reports installed |
| The checkout was produced by `git clone` | Treat the graph as absent: hooks are not copied by clone, so no repository-local hook exists to run for that checkout. Build it once from a workspace scan rather than waiting for a hook to fire |

## Instead of

Expand All @@ -100,3 +103,5 @@ dispatch; deciding whether a graph result can stand as evidence in a plan.
- https://getautonoma.com/blog/parallel-ai-agent-prs — map each task to the files it will touch via the dependency graph before assigning; parallelize only disjoint file sets
- https://www.tiarebalbi.com/en/blog/code-graphs-coding-agents-delivery-shape — a graph MCP exposing ten tools costs tens of thousands of context tokens whether queried or not
- https://github.com/Graphify-Labs/graphify — `explain`/`path`/`query --budget`, `update` (AST-only, no LLM), `hook install` post-commit/post-checkout; exit-0-on-error, empty `graph` metadata, and the query-vs-explain quality gap measured on graphifyy 0.4.23 with a 1,306-node graph, 2026-09-04
- https://git-scm.com/docs/githooks — `post-commit` "is invoked by git-commit"; `post-merge` "is invoked by git-merge, which happens when a `git` `pull` is done on a local repository"; `post-checkout` "is also run after git-clone, unless the `--no-checkout` (`-n`) option is used"
- Local reproduction 2026-09-16 (git 2.50.1, macOS): in a clone carrying all three hooks, a fast-forward `git pull` fired `post-merge 0` alone, and a divergent `git pull` that created a merge commit also fired `post-merge 0` with no `post-commit` — a merge commit does not run `post-commit`. A fresh `git clone` of that repository carried no non-sample hooks. Source read of graphifyy 0.4.23 `hooks.py:186-187` shows `_install_hook(hooks_dir, "post-commit", …)` and `"post-checkout"` only, with zero `post-merge` occurrences in the file
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
id: infrastructure-agent-orchestration-escape-hatch-uses-as-a-knowledge-gap-signal
domain: infrastructure
category: agent-orchestration
applies_to: [general]
confidence: field-tested
sources:
- https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/resolving-code-scanning-alerts
- https://github.blog/changelog/2025-07-01-delegated-alert-dismissal-for-code-scanning-is-now-generally-available/
last_verified: 2026-09-16
related: [infrastructure-agent-orchestration-session-completion-gates, infrastructure-agent-orchestration-autonomous-decision-rulings, qa-document-verification-spec-document-gates, backend-common-llm-binding-instructions-for-agents]
---

# Recording Every Use of a Grounding Gate's Escape Hatch

## When this applies

You are building or reviewing a gate that requires each decision to cite a
source — a wiki page, an ADR, a spec section — and that offers a marker letting
an uncitable decision through (`[no-wiki]`, `# noqa`, a dismissal reason). Also
when the knowledge base behind such a gate stops growing while plans keep
meeting situations it does not cover.

## Do this

1. **Emit one record at the point the gate grants the pass.** In the gate
script, the line before the `continue`/`return 0` that skips validation
appends a row to a gap queue — not the pass/fail line the gate already
prints. The hatch is the only place that knows a decision had no source, and
the gate is the only actor present at every use of it.

2. **Put the decision's own text in the record**, with the run or plan id and a
timestamp, so the row is routable into an ingest pipeline without reopening
the plan:

```sh
if [ "$basis" = "[no-wiki]" ]; then
printf '%s\t%s\t%s\n' "$(date -u +%FT%TZ)" "$PLAN_ID" "$decision" >> "$GAP_QUEUE"
continue
fi
```

3. **Make the hatch's reason a required, enumerated field**, and keep the
reasons that mean different things apart: *no page exists* is a knowledge gap,
*a page exists but was not found* is a routing defect, *out of scope for the
knowledge base* is neither. A single undifferentiated marker merges the three
into one unreadable pile.

4. **Keep the hatch passing.** Its value is the honest signal it collects;
turning it into a failure buys a plan that cites the nearest unrelated page
instead, which the gate cannot detect.

5. **Reconcile the two counts on a schedule.** Count hatch uses over a period
and compare against rows in the gap queue; the emitter is wired only while
the numbers match. A gate whose hatch fires and whose queue stays empty is
the failure this page exists to catch.

## Edge cases

| Case | Then |
|------|------|
| The gate's stdout is parsed by its caller | Append the record to a file path from the environment, never stdout — a new line in a parsed stream is a protocol change |
| The gate runs in a subshell or a pipeline | Write with `>>` to an absolute path; a variable accumulated in a subshell is discarded at its exit |
| The gate is a prose instruction in a skill document rather than a script | Move the recording into whichever script runs the check; an instruction to "note this as an ingest candidate" is executed only when the author remembers |
| Several runs write the queue concurrently | Append single lines under the platform's atomic-append size and let the reader de-duplicate; a read-modify-write of the whole queue loses rows |
| The same gap recurs every run | Keep the duplicates and de-duplicate at ingest time — repetition count is the priority signal for which page to write first |
| The hatch is used because the knowledge exists but the author did not find it | Record it under the routing-defect reason; the fix is an index trigger line, not a new page |

## Instead of

| If you are about to | Do this instead | Why |
|---------------------|-----------------|-----|
| Document in the skill's prose that an escape-hatch use should be filed as an ingest candidate | Emit the row from the gate script at the moment it grants the pass | Prose relies on the author who was just let off to do extra work; the gate is already running and already has the decision text |
| Have the gate print a warning line for an ungrounded decision | Append it to a durable queue as well | A warning scrolls past with the rest of the run output and is gone by the time anyone writes pages |
| Count the gate's pass/fail results as the health metric for the knowledge base | Count hatch uses per run, and the gap queue's depth and age | Pass/fail measures whether plans satisfied the gate; only the hatch count measures what the knowledge base does not yet cover |

## Sources

- https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/resolving-code-scanning-alerts — the canonical shape of a recorded escape hatch: dismissing an alert requires choosing a reason, "the dismissal comment is added to the alert timeline", the comment is readable as `dismissed_comment` on the alerts API, and dismissed alerts stay in the Closed list for later review
- https://github.blog/changelog/2025-07-01-delegated-alert-dismissal-for-code-scanning-is-now-generally-available/ — the recorded hatch extends to the reviewer: a dismissal request can be approved or rejected with a comment, and dismissal requests are listed and reviewed through dedicated REST API endpoints, so the hatch and its review are both readable outside the UI
- Field evidence 2026-09-16 (dev-loop 1.22.0): `skills/wiki-plan/scripts/plan-gate.sh:166` passes an ungrounded decision with `[ "$basis" = "[no-wiki]" ] && continue` and records nothing, while `skills/wiki-plan/SKILL.md:135` asks in prose for the decision to be "noted as an ingest candidate". Measured against a wiki of 276 non-index pages, `log.md` carries exactly one `gap` entry, dated 2026-07-11 — the prose instruction produced one record in two months of planning
Loading
Loading