From 1ff1aaf51484f9a61fbc0611eb725176ebc6dd2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=98=81=EA=B8=B0?= Date: Thu, 30 Jul 2026 17:46:14 +0900 Subject: [PATCH 1/2] knowledge: ingest 4 verified insight(s) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - platforms/processes/non-interactive-cli-invocation (new): a non-interactive flag is not a closed stdin — pair it with "$LOG" 2>&1 & disown` ([platforms-processes-background-services]) | +| Tool authenticates over the network | Add the tool's fail-fast switch so a missing credential errors instead of prompting: `ssh -o BatchMode=yes`, `GIT_TERMINAL_PROMPT=0`, `DEBIAN_FRONTEND=noninteractive` | +| Any unattended call | Wrap in a timeout so a block fails loudly: `timeout cmd …` (on macOS, `gtimeout` — see [platforms-tools-bsd-vs-gnu-cli]) | + +2. **Give the call a deadline rather than watching it.** `timeout` will "Start + COMMAND, and kill it if still running after DURATION", exiting 124 when that + fires — a distinguishable signal that the call blocked, instead of an agent turn + that hangs until something else kills it. + +3. **When it still hangs, locate the boundary before blaming either side.** Zero + output is compatible with two very different faults: the request never left the + client, or the far side never answered. Split them with evidence from the far + side — the server/gateway access log for that source IP and time window, or a + packet/connection count: + +| Observation at the far side | Conclusion | Next action | +|-----------------------------|------------|-------------| +| No request recorded in the window | The call never got that far — it is blocked locally (stdin, auth prompt, DNS, proxy) | Re-run with `/{exit}'`, a line + range, or a section selector) rather than running it over the whole file. This is + standard practice in the tools themselves: Vale scopes are markup-aware and "Any + scope prefaced with `~` is negated", and markdownlint rules take + `code_blocks: false` to exclude quoted code from prose rules. `pgrep` hard-codes + the same defense — "The running pgrep, pkill, or pidwait process will never + report itself as a match." + +4. **Record verdicts as scoped conditions, never as a global count.** Write "0 + matches outside §Audit" or "every match is inside a fenced block", not "1 match + found". A fixed number is invalidated by the next edit — including the edit that + quotes the finding — so a count-based verdict decays into a false statement while + looking precise. + +5. **Re-run the whole gate set after the edit and compare against the pre-edit + pass count.** Your edit can break a check owned by a different section or a + different task ([qa-process-regression-scope]). A baseline number (`60 → 61`) is + what distinguishes "my change fixed one" from "my change fixed one and broke two". + +## Edge cases + +| Case | Then | +|------|------| +| The quoted pattern must stay in the document (it is the audit record) | Keep the quote and narrow the check's scope; the document's job is to be readable, the check's job is to be scoped | +| Fixing the report by quoting the offending match adds another match | Stop counting globally and switch to the scoped condition in step 4 — each quote-to-fix round otherwise raises the count and re-falsifies the statement | +| Gate anchors on a line count you must change | Update the gate and the document in the same commit, and say so in the PR ([qa-process-acceptance-criteria]) | +| The failure surfaces in another task's or another agent's check log | Attribute before repairing: identify which file the failing pattern targets, since a cross-file gate makes your edit look like their regression | +| The gate is genuinely wrong (it forbids a correct sentence with no replacement available) | Change the gate, with a control proving it still catches the defect it owns — do not reword a correct document into a worse one | +| You are authoring the gate rather than the document | This page covers the author's side; gate construction and its controls are a separate concern → [testing-quality-tests-that-cannot-fail] | + +## Instead of + +| If you are about to | Do this instead | Why | +|---------------------|-----------------|-----| +| Edit a gated document and run only the check you were fixing | Grep the gates for anchors on that file first, then re-run the full set against a baseline count | Line-count and substring anchors break silently, and the breakage lands in a check you never looked at | +| Write "X defines/mandates two variants" when describing an upstream contract | Write the observable shape: "the table has two rows and no Y row" | A vocabulary gate cannot separate describing from redefining, so the defining verb fails a sentence whose content is correct | +| Run an audit pattern over the whole document that quotes it | Bound it to the normative region by heading range or line range | The quotation is a match, so the whole-file run measures the document's prose about itself | +| Record "grep found 0 hits" as the audit result | Record the scoped condition that must hold ("no hits outside §Audit") | The bare count is true only for the file revision that produced it and silently becomes false on the next edit | + +## Sources + +- https://docs.vale.sh/checks/existence — the check "looks for the 'existence' of particular tokens", transformed into a word-bounded non-capturing group: a lexical gate matches patterns, not intent +- https://docs.vale.sh/topics/scopes.md — scopes restrict where a rule applies via markup-aware selectors; "Any scope prefaced with `~` is negated" and scopes can be chained, so checks can be kept off regions like code examples +- https://github.com/DavidAnson/markdownlint/blob/main/doc/md013.md — rules expose `code_blocks`, `tables`, `headings` booleans (default `true`) so quoted code can be excluded from a prose rule +- https://man7.org/linux/man-pages/man1/pgrep.1.html — "The running pgrep, pkill, or pidwait process will never report itself as a match" — self-exclusion is designed in because self-matching is the expected failure + +## Field context + +Distilled from 2026-07 RFC/plan-authoring sessions in this repo. A vague-word audit +of `docs/ROADMAP.md` reported 1 global hit — the audit command's own quoted pattern — +and quoting the finding to fix it raised the count to 3, while an `awk`-scoped run +over the normative region reported 0; the same self-reference appeared twice more +(a negative-control example that always matched, and a `docs/*.md` glob matching its +own document 45 times). Separately, adding the sentence "defines only the two +variants arena and pool" to an RFC failed a sibling task's vocabulary gate +(`(arena|pool)…(재정의|정의한다|규정한다)`); rephrasing to "the contract table has +two rows and no heap row" restored the suite from 60 to 61 passing, and a pre-edit +anchor survey of that file found three further anchors — a line count, a section +substring, and a verbatim upstream sentence — all preserved by the same edit. diff --git a/wiki/qa/index.md b/wiki/qa/index.md index 92b7105..a87d73c 100644 --- a/wiki/qa/index.md +++ b/wiki/qa/index.md @@ -17,6 +17,12 @@ Match your situation to a "load when" line; load only matching pages. | [severity-and-priority](process/severity-and-priority.md) | Triaging a bug — deciding how bad it is and when it gets fixed; a triage stalled on a severity debate | | [post-release-verification](process/post-release-verification.md) | A release just deployed to production; defining what "released safely" means; an incident revealed a release was broken for hours before anyone noticed | +## document-verification + +| Page | Load when | +|------|-----------| +| [editing-a-gated-document](document-verification/editing-a-gated-document.md) | Editing or rewording a document that grep/regex gates or a lint config check; a gate fails on wording whose meaning did not change; describing what an upstream spec says without tripping a "do not redefine it" gate; a check matches the pattern your own document quotes; recording an audit verdict inside the document that was audited; deciding which checks to re-run after editing a gated document | + ## environments | Page | Load when | From 0f848d8bf2beff4af6400a8ae8cbc033acd46a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=98=81=EA=B8=B0?= Date: Thu, 30 Jul 2026 17:47:44 +0900 Subject: [PATCH 2/2] knowledge: add Decision Log block to the flush report Required by the RTB decision-log PR gate: intent, rejected alternatives, and reviewer focus points (including the qa/index.md conflict with PR #10). --- .dev-loop/INGEST_REPORT.md | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/.dev-loop/INGEST_REPORT.md b/.dev-loop/INGEST_REPORT.md index fd8052a..051256b 100644 --- a/.dev-loop/INGEST_REPORT.md +++ b/.dev-loop/INGEST_REPORT.md @@ -161,3 +161,45 @@ Body lines 83 / 82 / 93 (limit 120) · all four required sections present on eac every `related:` id and inline `[page-id]` resolves (13 checks, 0 misses) · each new page listed in its domain index with a multi-use-case "load when" · every index relative link resolves · no banned vague qualifiers · `log.md` entry appended. + +## Decision Log + +**의도** +- 큐에 쌓인 4건을 3페이지로 인그레스트한다. qa 2건(자기참조 grep · 어휘 게이트/앵커)은 + "게이트가 걸린 문서를 편집하는 쪽"이라는 **한 케이스**라서 1페이지로 합쳤다 + (`AGENTS.md` "one case per page" + 지시문이 서로를 필요로 함). +- 후보의 *why*를 그대로 받지 않고 실측으로 교정했다: `--body-file` 차단 원인은 + "따옴표 때문"이 아니라 **따옴표=추출 실패 / 미확장 변수=경로 부재**의 두 모드이고 + 따옴표 친 리터럴 경로도 실패한다(본문 표에 5변형 실측). +- 열린 PR(#6~#10)까지 중복 검사 대상에 포함했다. `main`만 보면 커버리지를 과소평가해 + #10과 같은 페이지를 또 만들 위험이 있었다. +- `INDEX.md`는 **의도적으로 건드리지 않았다** — #10이 이미 qa 라우트 라인을 갱신하므로 + 충돌면을 `wiki/qa/index.md` 한 훅으로 줄였다. + +**배제한 대안** +- *insight 1을 `background-services`에 병합* → 기각. 그 페이지의 케이스는 *지속성*이고, + 블로킹 stdin을 넣으면 "load when"이 흐려진다(양방향 링크로 대체). +- *insight 2를 `portable-shell-scripts`에 병합* → 기각. 그 페이지 규칙은 "모든 확장을 + 따옴표로 감싸라"인데 이 건은 한 인자를 리터럴로 쓰라는 것 — 트리거도 다르고 규칙이 + 충돌해 보인다. 새 페이지에 "이 페이지는 인자 하나만 좁히며 다른 곳의 무따옴표 확장을 + 허용하지 않는다"를 명시. +- *insight 2용 새 카테고리(`policy-gates`)* → 기각. 두 번째 멤버가 안 보이는 1페이지 + 카테고리. 메커니즘이 확장 타이밍이라 `shells`가 맞다. +- *insight 1을 `debugging`으로* → 기각. 바꾸는 산출물이 호출 명령이므로 소유 도메인 우선 + 규칙에 따라 platforms(진단 절반은 `debugging-methodology-reproduce-first`로 링크). +- *qa 2건을 #10 머지까지 보류* → 기각. 범위 축소는 소유자 판단이므로, 대신 충돌 위치와 + 해소법(헤딩 1개 + 행 2개)을 위에 명시했다. +- *#10 브랜치를 base로 스택 PR* → 기각. 스킬이 `--base main`을 요구하고, 리뷰 diff에 + #10 변경이 섞인다. + +**리뷰어가 볼 곳** +1. `wiki/qa/index.md` — #10과 충돌 예정 지점. **헤딩 1개 유지 + 행 2개**로 해소. +2. `wiki/qa/document-verification/editing-a-gated-document.md` — #10의 페이지와 + 중복이 아닌지(저자 측 vs 게이트 저자 측 분담)가 이 PR의 핵심 판단. +3. `command-text-inspected-before-execution.md`의 Field context 5변형 표 — + `hooks/pre-flush-pr-gate.sh:56` 패턴으로 재현 가능. +4. confidence 등급: 1·2는 `verified`(공식 문서+재현), 3+4는 `field-tested` + (위험은 문서화되어 있으나 지시문은 현장 유래). 1번 페이지의 클라이언트/서버 분리 + 단계는 문서 근거가 아니라 현장 유래라서 Field context로 분리해 표기했다. +5. **[추정]** `platforms/shells`에 2페이지(이식성 + 확장 타이밍)가 앞으로도 응집적으로 + 남을 것이라는 판단은 추정이다 — 유사 사례가 더 쌓이면 별도 카테고리가 나을 수 있다.