diff --git a/docs/doctoring/product-goal-directive.md b/docs/doctoring/product-goal-directive.md index d752033602..3e82a20865 100644 --- a/docs/doctoring/product-goal-directive.md +++ b/docs/doctoring/product-goal-directive.md @@ -86,3 +86,757 @@ fixed: conventions this record reconciles against. - ContextualWisdomLab/.github#1429 — the PR carrying this change and Devin Review's findings. + +## 2026-09-01 revision: three sections gained new substantive content + +- **Date:** 2026-09-01 +- **Subject:** the owner re-issued the full nine-section directive verbatim via + a `/loop` invocation in an active autonomous session. A word-for-word + comparison against the stored text (saved to a scratch diff before editing, + not committed) found sections 1, 2, 4, 5, 6, and 9 re-authored in + substantially the same words — condensed phrasing, English terms swapped + for Korean equivalents, no new obligation — so those sections were left + untouched in `docs/product-goal-directive.md` to avoid rewriting stable + wording for no substantive gain. Three sections contained genuinely new + sentences, absent from every prior version of this file, and were added in + place (inside the existing verbatim quote blocks, appended or inserted at + the sentence they logically extend — not as a separate reconciliation note, + since nothing here contradicts an existing binding convention): + + 1. **§3 (research/documentation traceability)** gained an explicit + decision-record standard: every decision must be written so that even + the author having forgotten the context, or a reader seeing it for the + first time, can reconstruct the problem, constraints, alternatives + considered, why one was chosen and the others rejected, the supporting + evidence, the risks, the expected effect, and the follow-up — with + concrete, vivid scenarios (not bare conclusions or unstated premises), + and links to the exact head SHA, logs, issues/PRs/ADRs, and experiment + results so another agent can verify, revise, or continue the same + judgment. This directly generalizes a discipline this session was + already practicing informally (e.g. the RED→GREEN evidence, coverage + numbers, and root-cause narratives recorded throughout + `docs/product-technical-gap-baseline.md`'s 2026-08-30/31 and 2026-09-01 + entries) into an explicit, binding requirement for all future entries. + 2. **§7 (realistic verification / load / container testing)** gained a + concrete, testable E2E acceptance criterion that did not exist before: + p95 per-page processing time ≤ 20ms, checked across every page (not a + sample), with any bottleneck removed and the page re-verified before it + can be considered passing. No repository in this org's current scope + (`.github`, `noema`, `contextual-orchestrator`, `naruon`) has this gate + wired into CI yet — it is recorded here as a new, tracked requirement + for whichever repo's web surface next needs an E2E load-test pass, not + as a claim that it is already enforced anywhere. + 3. **§8 (LLM, orchestration, embedding)** gained two new principles, both + absent from the 2026-08-30 text: + - **Never hardcode an LLM provider *group* name.** Group/pool names + (e.g. `orchestrator/free`, `orchestrator/auto`) are management/display + aliases only; code, config, tests, and routing conditions must decide + model selection, fallback, and feature availability from + auto-discovered, verified model characteristics (modality, context + window, reasoning capability/effort, tool calling, structured output, + streaming, price/latency/availability/accuracy) so that a renamed or + replaced provider/group never breaks a feature branch. This + generalizes, and does not relax, the existing pool-routing note above + (§8's first note, 2026-08-30): that note is about *which pool* each + CI consumer is bound to (still governed by + `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md`); this + new sentence is about *how code decides behavior once bound to a + pool* — never by matching the pool's string name. + - **No uniform hardcoded LLM request timeout.** The application/agent/ + gateway layer must not impose a single timeout ceiling on LLM calls; + the default is unlimited (`null`), since transport failures already + terminate via the upstream provider's own timeout/error path (see + `scripts/ci/noema_review_gate.py`'s unbounded design, reconciled + against the now-superseded #1438 in the 2026-09-01 entries of + `docs/product-technical-gap-baseline.md`, and the removed + 120-second/four-hour-window history in this same doctoring file's + companion entries). Per-model timeouts become available only through + an admin-facing web surface with full CRUD (query/set/clear/restore), + units, priority, inheritance, input validation, and an audit trail as + an explicit API contract; an admin-configured value is the *only* + thing allowed to bound a call, and even then a bare elapsed-time + cutoff must never cancel an in-progress reasoning/streaming/tool-call + turn. Logs must distinguish user-initiated cancellation, + provider-side termination, and admin-configured timeout as three + distinct, separately recorded outcomes. No repository in this org's + current scope has this admin timeout-management surface implemented + yet — it is a new, tracked product gap (see + `docs/product-technical-gap-baseline.md`'s 2026-09-01 entry), most + naturally owned by `contextual-orchestrator`'s existing `/admin` + console (`contextual_orchestrator/admin.py`) since that is where + model/pool configuration already lives, not by any single CI + consumer. +- **Decision record:** no `docs/adr/` entry yet for the admin-timeout-management + surface (§8, second bullet above) — it is substantial enough to eventually + need one once a repository begins implementing it; this doctoring entry and + the gap-baseline entry are the interim record. +- **PR:** ContextualWisdomLab/.github (this change's own PR — see the PR + description for the exact number). + +## Audit trail (2026-09-01 revision) + +- `docs/product-goal-directive.md` — §3, §7, §8, and the top-of-file revision + note. +- `docs/product-technical-gap-baseline.md` — the 2026-09-01 entry tracking the + two new, currently-unimplemented product gaps this revision introduced + (E2E p95 20ms gate; admin per-model timeout management). +- `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md` — the still- + governing pool-routing policy this revision's provider-group-name principle + does not relax. + +## 2026-09-01 follow-up: new §10 crystallizes the Strix pool pin + +- **Date:** 2026-09-01 (same day, a second `/loop` invocation following the + revision above) +- **Subject:** the owner added one new line — "orchestrator/free 로 고정" + ("fix/pin to orchestrator/free") — as an explicit tenth numbered item, + where §8 previously only carried this as an annotation below the verbatim + quote (a CodeRabbit-flagged note describing `Strix` on the provider-diverse + `orchestrator/auto` pool, followed by a second, superseding note recording + that `.github/workflows/strix.yml` was later changed to hardcode + `orchestrator/free` and fail closed on any other value). Verified this + claim directly against the current `strix.yml` before writing the new + section (not just trusting the prior note): both `STRIX_MODEL_REQUESTED` + and `STRIX_MODEL`/`strix_llm` gating `case` statements accept only + `orchestrator/free`/`contextual-orchestrator/orchestrator/free`, and + `::error::` on anything else — confirming the pin is still in force at the + time of this doctoring entry, not merely claimed by an older note that + could itself have drifted. +- **What changed:** added `## 10. Contextual-orchestrator pool pin` to + `docs/product-goal-directive.md`, quoting the new line verbatim, with a + context paragraph (not inside the quote) explaining that this crystallizes + an already-implemented decision rather than introducing a new one, and + that it supersedes §8's first (CodeRabbit) note's "Strix → + `orchestrator/auto`" framing specifically — that framing was already + superseded by §8's second note; §10 now makes the current state + discoverable without needing to read a superseded-vs-superseding note pair. + Updated the "nine sections" → "ten sections" references in the file's + intro and the `/goal` pointer text (which also gained the new section to + its parenthetical list of the sections a `/goal` session must treat as + applicable every cycle). +- **Decision record:** none new — this doesn't change the pool-routing + policy itself, only where it is recorded; `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md` + remains the ADR of record. +- **PR:** ContextualWisdomLab/.github (same PR as the 2026-09-01 revision + above, or its immediate follow-up commit — see the PR description). + +### Audit trail (this follow-up) + +- `docs/product-goal-directive.md` §8 (both existing notes, read but not + edited) and new §10. +- `.github/workflows/strix.yml` — the live source verified before writing + §10, not merely cited from memory of the existing note. + +## 2026-09-01 second follow-up: §10 wording refined with an explicit scope qualifier + +- **Date:** 2026-09-01 (same day, a third `/loop` invocation) +- **Subject:** the owner re-issued item 10 with an added qualifier: + "Contextual-Orchestrator의 모델은 **GitHub Actions Workflow 이용에 관해** + orchestrator/free 로 고정" ("...is fixed to orchestrator/free **with + respect to GitHub Actions Workflow usage**"). The bare one-line version + recorded in the prior follow-up above could be misread as pinning + `contextual-orchestrator`'s pool choice for *every* caller, contradicting + §8's own general-capability framing (broad model/modality support, + five-secret auto-discovery as a product-level design principle for the + orchestrator itself). The qualifier makes explicit what the live + `strix.yml` evidence already implied: this pin governs the three + required-check GitHub Actions Workflows (`OpenCode`, `Noema`, `Strix`), + not the orchestrator's general product capability for other callers + (e.g. a future non-CI consumer, or an end-user-facing integration). +- **What changed:** updated §10's verbatim quote to the fuller wording and + expanded its context paragraph to state the CI-workflow-scoped reading + explicitly, cross-referencing §8's own general-capability framing so the + two sections read consistently rather than appearing to conflict. +- **Decision record:** none new — same as the prior §10 follow-up, this is + a wording clarification of an already-implemented, already-recorded pin, + not a policy change. +- **PR:** ContextualWisdomLab/.github (same PR as the two entries above). + +## 2026-09-02 revision: five sections gained new substantive content + +- **Date:** 2026-09-02 +- **Subject:** the owner re-issued the full ten-section directive again, this time as a genuine + chat-turn message (not a `/loop` invocation) titled "아래는 일반 지침" ("general guidance below"). + A section-by-section comparison against the stored text found §1, §3, §6, and §8 re-authored in + visibly condensed form — same substance, shorter Korean, no new obligation — left untouched per + the same policy as the 2026-09-01 revision. §2, §4, §5, §7, and §9 each contained genuinely new + sentences absent from every prior version of this file, added in place (inside the existing + verbatim quote blocks, or as a new quoted addition immediately following the existing block where + the new material reads as a distinct addendum rather than an in-line insertion): + + 1. **§2 (concurrent operation / root-cause fixes)** gained an explicit "immature core" protocol: + when a needed core dependency is immature, the consumer must never duplicate, work around, or + exclude it — instead develop the missing RED test, contract, feature, docs, and release *in the + owner repo*, get it through that repo's own CI to GREEN, and only then connect the consumer to + the resulting versioned release. Excluding a dependency is reserved for two cases only: the + bounded context itself is wrong, or there is genuinely no shared need. This directly formalizes + a discipline this session was already practicing (e.g. this same session's earlier passes fixing + `contextual-orchestrator`'s discovery-retry gap at the owner rather than working around it in a + consumer) into an explicit, binding rule — and it is the same principle §9 restates from the + repository-selection angle ("공통 기능은 core owner로 추출해 통합 CI로 개발한다"), so the two + additions cross-reference each other. Also gained one new reference tool: + https://github.com/epoko77-ai/im-not-ai for Korean-language phrasing/documentation/translation + polishing, explicitly scoped to preserve meaning, facts, figures, and proper nouns (not a + free-form rewrite tool) — added alongside the existing ponytail/superpowers/code-review-graph/ + codegraph tool list already in this section, matching where the new text placed it. + 2. **§4 (UX/UI and customer-facing expression)** gained the largest single expansion in this + revision: (a) an explicit UI-composition principle ("all UI is reusable objects, pages are + compositions of them"); (b) a named list of Storybook states to isolate-develop and document + (normal/loading/empty/error/permission/responsive/interaction) replacing the vaguer "scene- and + edge-case-specific events" wording; (c) an explicit shadcn/ui-vs-Storybook clarification + (shadcn/ui is a component *source*, not a Storybook substitute — the two are not in a + replace-one-with-the-other relationship); (d) an explicit frontend-stack-flexibility principle + (no fixed stack; React/Vite/shadcn/ui/jQuery 4 and others are acceptable when they meet + security/maintainability/standards/accessibility/performance bars); (e) a specific Keyverse + integration pattern not previously recorded anywhere in this file (Keyverse stays the + authentication *backend* via Direct Grant/ROPC or the Keycloak REST API, but login/signup/ + account-recovery screens are the product's own forms, not a Keyverse-hosted redirect page); and + (f) a genuinely new, concrete i18n architecture mandate: eight named languages (한국어·영어· + 일본어·중국어·베트남어·스페인어·독일어·프랑스어 — ko/en/ja/zh/vi/es/de/fr), per-language + Storybook/E2E testing for width/wrap/CJK/text-expansion/font-fallback/locale-format issues + (truncation, overlap, meaning-loss — not a single default-locale screenshot pass), and — the + load-bearing part — **the translation ledger must be a versioned DB resource, never static + files or a JS bundle**: server/native code fetches only the current screen's keys with caching, + the browser is never handed the whole catalog or heavy i18n JavaScript, and no SPA architecture + may be assumed. If no shared translation-management product exists yet, a new repository must be + stood up to provide per-product translation review/approval/deploy/rollback API plus an admin + UI. This i18n architecture requirement is recorded as a new, currently-unimplemented, + concrete product gap — this session did **not** audit naruon's (or any other product's) current + i18n implementation against it in this pass; that audit is deliberately deferred to a future Gap + increment (see `docs/product-technical-gap-baseline.md`'s 2026-09-02 entry), consistent with + this directive's own "one Gap increment at a time" philosophy rather than trying to verify every + product's compliance in the same pass that records the requirement. + 3. **§5 (architecture, naming, and database conventions)** gained a concrete repo-responsibility + split for the org's ontology pipeline, added as a quoted addendum after the existing + Devin-Review naming reconciliation (not merged into the original 2026-08-30 quote block, since + it reads as new material rather than a correction to it): ConceptWeave owns the + observe→discover→propose→align→validate→review→publish pipeline and semantic release; + semantic-data-portal owns catalog/governance/consumption; context-graph-contracts owns + interop contracts; enterprise-architecture-core owns the Context Map and cross-cutting + decisions — domain truth and Ubiquitous Language themselves stay with the product owner, not + any of these four. Also new: an immutable-release data contract for ontology concepts + (evidence/provenance/validity/confidence/status/deprecation/locale label required on every + released concept/relation/dimension/measure/mapping); a consumer-boundary prohibition + (consumers use only released API/contract/ACL — no file copies, no cross-service SQL, no + unapproved publication); and an explicit rule that the UI translation ledger (§4, above) and the + ontology label ledger (this section) must never share a store — two distinct versioned + resources with two different owners. Cross-checked `semantic-data-portal`'s description here + against its existing entry in `docs/CWL-MASTER-CONTEXT.md` (the higher ontology/catalog/ + governance plane above naruon's doc KG; SDP is not that store) — consistent, this addition just + names the upstream pipeline stages and the two cross-cutting-decision repos that file does not + yet name explicitly (see the §9 reconciliation note below for the same verification gap). + 4. **§7 (realistic verification, load, and container testing)** gained two anti-gaming clauses for + the p95≤20ms criterion the 2026-09-01 revision introduced: never satisfy it by shrinking the + sample, excluding measurements, or an unrealistic cache warm-up; and when the JS + bundle/heap/DOM/hydration/main-thread/GC is the actual memory or latency driver, the fix is to + replace the dependency or frontend stack rather than accept the slower ceiling. Both close off + the two most tempting ways to make the existing gate pass without fixing anything real, and + reinforce (not change) the section's existing profile-first-then-Rust-if-proven-necessary + approach. + 5. **§9 (reference libraries, ecosystem repositories)** roughly tripled in size and gained explicit + per-repo responsibility statements for most entries for the first time. New repos named: + `.github`, `enterprise-architecture-core`, `context-graph-contracts`, `ConceptWeave`, + `semantic-data-portal`, `noema`, `EgressWeave`, `OriginWeave`, `pingora-gateway`, + `quarantine-sandbox-runtime`, `pg-llm-batch`, `EmbedRelay`, `inkspan`, `DiagramWeave`, + `mhtml-etl-gateway`, `appguardrail`, plus an explicit "domain product/composition consumer, not + core" classification for `naruon`, `LineageWeave`, `psychometrics-commons`, `disksage`, + `PolicyWeave`, `CalendarWeave`, and `supply-chain-control-plane`. Cross-checked against + `docs/CWL-MASTER-CONTEXT.md`: `semantic-data-portal`, `pg-llm-batch`, `appguardrail`, `inkspan`, + `wardnet`, `keyverse`, `naruon`, `TEPP`, `fast-mlsirm`, `RankWeave`, `ThreadWeave`, `disksage`, + `LineageWeave`, `contextual-orchestrator`, and `noema` already appear there and this section's + descriptions are additive, not contradictory. `ConceptWeave`, `context-graph-contracts`, + `enterprise-architecture-core`, `EgressWeave`, `OriginWeave`, `pingora-gateway`, + `quarantine-sandbox-runtime`, `EmbedRelay`, `DiagramWeave`, `mhtml-etl-gateway`, + `psychometrics-commons`, `PolicyWeave`, `CalendarWeave`, and `supply-chain-control-plane` could + **not** be cross-checked: `CWL-MASTER-CONTEXT.md` does not yet name them, and this session's + repository access (`.github`, `noema`, `contextual-orchestrator`, `naruon`) does not extend to + them. Recorded verbatim anyway, per this file's own conflict/durability policy, with a tracked + follow-up gap to add them to `CWL-MASTER-CONTEXT.md`'s catalog once an agent with access (or the + owner) can confirm the responsibility split against their actual current state. + + Also updated §8 with a short note (not a change to the verbatim quote) observing that this + revision's §8 restatement again mentions "`orchestrator/free` 고정" but as a bare clause inside + §8's body rather than the separately scope-qualified §10 item, and that this compression does not + reopen or loosen §10's already-evidence-verified "GitHub Actions Workflow 이용에 관해" scope + qualifier — a shorter restatement omitting detail recorded elsewhere in the same document is not a + reversal of that detail. +- **Decision record:** none yet in `docs/adr/` for the i18n-DB-versioned-resource architecture or the + ontology-pipeline repo split — both are substantial enough to eventually warrant one once a + repository begins implementing against them; this doctoring entry and the gap-baseline entry are + the interim record, consistent with how the 2026-09-01 admin-timeout-management gap was handled. +- **PR:** ContextualWisdomLab/.github (same branch/PR as the 2026-09-01 revisions above — + `docs/update-product-goal-directive-2026-09-01` — continued rather than forked into a new PR, since + this is the same ongoing "keep the directive doc current" effort). + +### Audit trail (2026-09-02 revision) + +- `docs/product-goal-directive.md` — §2, §4, §5, §7, §9 (new content), §8 (new note), and the + top-of-file revision summary. +- `docs/CWL-MASTER-CONTEXT.md` — cross-checked for every repo name in the new §5/§9 content; the + entries it does and does not already carry are both recorded above. +- `docs/product-technical-gap-baseline.md` — the 2026-09-02 entry tracking the two new, + currently-unimplemented product gaps this revision introduces (the i18n DB-versioned-resource + translation-ledger architecture; the ontology-pipeline repo-responsibility split awaiting an + `enterprise-architecture-core`/`context-graph-contracts`/`ConceptWeave` cross-check), plus the + tracked follow-up to add the not-yet-cross-checked §9 repo names to `CWL-MASTER-CONTEXT.md`. + +## 2026-09-02 Devin Review reconciliation: one real internal contradiction, one real misplaced quote + +- **Date:** 2026-09-02 +- **Subject:** Devin Review's automated review of this PR (`#1659`) flagged 5 findings against the + 2026-09-02 revision above. Two were `BUG`-severity and, verified directly against the file before + acting (not taken at face value, per this session's standing verification discipline), both turned + out to be real defects introduced by that revision's own edits: + 1. **§7's newly-added container-requirements sentences (Docker/Podman/Colima substitution, + `shm_size`/PostgreSQL auto-tuning, compose-first k8s portability, fixed-then-overridable + container project naming, MLX/CPU/CUDA/OpenCL ADR requirement) had been appended after the + English "Addition (2026-09-02)" commentary paragraph instead of inside the `>` blockquote + above it.** Confirmed by direct inspection: the quoted §7 block ends at "...점검한다." and the + Korean container sentences sat at the tail of the English commentary that follows, with no `>` + prefix. Since this file's own "How to point a `/goal` session at this directive" section frames + the ten sections as extractable quoted blocks, any consumer pulling just the `>`-quoted text + would silently miss binding directive content. **Fix:** moved the Korean sentences verbatim into + the end of the §7 blockquote itself (no paraphrasing, no wording change), leaving the English + commentary paragraph containing only the anti-gaming-clause explanation it was originally written + for, with a short note recording the move and crediting Devin Review's finding. + 2. **§8's "LLM Provider group 이름을... 하드코딩하지 않는다" and §10's "orchestrator/free 로 고정" + read as a direct contradiction in isolation** — Devin's own framing, "agents cannot satisfy both," + is accurate as far as it goes. Verified this was a genuine gap: the existing §8/§10 notes already + explained the *scope* (CI-consumer workflows vs. general product capability) but never explicitly + reconciled §8's literal "하드코딩하지 않는다" against §10's own admitted hardcoding of a group-name + string in `strix.yml`'s `CONTEXTUAL_ORCHESTRATOR_POOL`. **Fix:** added a new note distinguishing + §8's actual target — **behavioral feature branching** in application/Agent/gateway code (never + select a model or change capability handling by string-matching a provider group name; drive + behavior from auto-discovered model characteristics instead) — from §10's **CI admission-pool + selection**, which changes no application code path or feature at all; it only tells a + security-critical required-check workflow which cost/ZDR-governed pool it may draw candidates + from, with every model inside that pool still chosen by the same auto-discovery §8 requires. No + directive quote was weakened or reopened by this reconciliation — both `>` blocks are unchanged. +- **Not acted on:** Devin's other three findings were re-statements of gaps this same PR already + records — "focused test remains unverified" (no pytest in Devin's own review sandbox; this session's + actual `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` run, `5 + passed`, is the real evidence, and no test in this repo pins `product-goal-directive.md`'s prose — + confirmed via `grep -rln "product-goal-directive" tests/`, no matches), "master context remains + unsynchronized" (already Gap 5 in the gap-baseline), and "unverified roles become binding policy" + (already Gap 4). All three are accurate observations of already-tracked, already-labeled gaps, not + new defects — no further action needed on them beyond what's already recorded. +- **Verification:** `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` + → 5 passed (this file's only executable contract, unaffected by directive-text edits); confirmed via + `grep` that no test pins `product-goal-directive.md`'s literal prose. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 third revision (second same-day chat message): eight sections gained new substantive content + +- **Date:** 2026-09-02. +- **Subject:** the owner re-issued the full directive a third time overall — a second genuine + chat-turn message this same day, again titled "아래는 일반 지침." A section-by-section comparison + against the then-current stored text (post the two prior 2026-09-02 reconciliations already recorded + above) found §3 and §4 re-authored in condensed form with the same substance and no new obligation + detected — left as-is, same policy as every prior revision. Every other section (§1, §2, §5, §6, §7, + §8, §9, and §10's existing pin) gained genuinely new content, added in place inside the existing + verbatim quote blocks or as new dated blockquote additions immediately following them, each with an + explanatory English note in the same style as prior revisions: + 1. **§1** gained one new sentence closing a loophole in "reach 0 open PRs": doing so is legitimate + only via merge or a verified successor's full delta takeover, never a bare Close. This directly + sets up §2's much larger addition below. + 2. **§2** gained a detailed six-category PR close/repair taxonomy — single-writer/DDD violations, + wrong base/merge conflicts, colliding ADR numbers, prematurely-Accepted reviews, unprotected + dependencies, and missing test/fixture/contract are all **repair findings, never close reasons**. + The repair path: downgrade to Draft/Proposed, non-force restack/retarget onto the owner's stack + (never force-push). Single-writer resolution is explicitly framed as **delta integration, not + discarding**: an unfixable PR needs a successor that fully inherits its delta and continues the + work; a PR blocked on an unlanded foundation stays open while the prerequisite gets completed; a + wrongful close gets recovered via reopen or successor. Close itself narrows to exactly four + legitimate cases (explicit user instruction, no valid delta, a malicious change, or a verified + successor's full takeover) — a "closed" label by itself is not closure without one of those four + behind it. + 3. **§5** widened the existing two-or-more-word DB-object naming rule to cover essentially every + named code entity (variables through directories), still snake_case-preferred, and added an + explicit boundary-conversion rule (external language/framework/contract naming conventions get + converted at an adapter/ACL boundary, not propagated inward — the same Anti-Corruption-Layer + principle this section already states generally, now applied specifically to naming). The + existing wardnet/grandfather-clause reconciliation from 2026-08-30 is explicitly noted as not + reopened: it stays scoped to existing CamelCase/PascalCase **DB objects** specifically. + 4. **§6** sharpened the existing Rust-first mandate into an explicit "Python is disfavored, never + chosen for LLM/agent convenience" rule with one narrow, ADR-tracked exception (a Python-only ML + runtime with no practical Rust alternative, scope/rationale/removal-condition recorded, hot path + still Rust), plus naming Rust as an explicit alternative to a Python-3.14 upgrade for GIL + bottlenecks. + 5. **§7** added "rendering" to the list of things to replace when the JS bundle/DOM/GC is the + memory/latency driver (previously "dependency·Frontend stack," now "dependency·rendering·Frontend + stack"). + 6. **§8** gained two things: a "connect via released API/client/schema" consumption pattern for + `contextual-orchestrator` integration (the same "immature core" principle §2 and §9 already state, + now stated a third time as the specific CO consumption contract — verified not to contradict the + adjacent "가능하면 반입해 쓰고... 수정한다" sentence, which is about CO importing *its own* upstream + dependencies, a different relationship); and a detailed CI integration architecture (`.github` + reusable-workflow-plus-thin-caller composition; exact-SHA verification across build/API-schema- + contract/E2E/model-behavior/security/SBOM/provenance; owner-side RED→fix→GREEN→release with a + consumer version bump on defects; a ban on mutable-head/branch-URL/cross-repo-source/workflow + duplication; an owner-issue-plus-expiration condition on any transitional bridge) — recorded as + the standard, explicitly not asserted as already-verified everywhere (see Gap 7 below). + 7. **§9** gained three things: a definitional framing of what "core foundation" actually means (a + selective, canonically-owned, versioned-contract-providing control plane — never a default + install; role/maturity confirmed from the *protected branch's* evidence, not an open PR's own + claims — directly matching this session's own established practice of treating "Current exact + authority" PR-body language as a claim to verify, not a fact); a five-domain regrouping of the + existing flat repo catalog (조직·계약 / 의미·데이터 / AI·운영 / Identity·보안·runtime / 재사용 + 기능); and a concrete elaboration of the "immature core" protocol's waiting-period mechanics + (a port/ACL/feature-flag/test-double boundary while waiting on an immature owner; an explicit + prohibition on reading the owner's raw source/DB/temp branch directly, not previously stated). + 8. **§10** gained three specific architectural constraints on its existing `orchestrator/free` pin, + each **verified against current source before being recorded**, not merely restated: free-pool + discovery/routing/fallback stays inside CO (confirmed — the sidecar provisions an in-process CO + instance; Strix talks to it only via a locally generated bearer token); the workflow itself has no + live path to specify a provider/model/group and never sees a raw provider credential (confirmed — + `strix.yml`'s `Gate Strix secrets` step hardcodes the model and rejects any override that isn't + the same value); missing capability fails closed with no paid bypass (confirmed — the sidecar's + `CONTEXTUAL_ORCHESTRATOR_POOL` validation is exactly this session's own earlier `auto`-removal + fix). Like the original §10 addition, this is the existing implementation made explicit, not a + new technical requirement. +- **Two new gaps recorded, not fabricated:** `docs/product-technical-gap-baseline.md`'s new 2026-09-02 + entry tracks two audit gaps this revision's new content surfaces but this reconciliation pass did not + fully verify — Gap 6 (`contextual-orchestrator`'s stdlib-Python core against the newly sharpened §6 + Python rule; partial evidence found — `library_research.md` already exists and the one genuinely + numeric hot path, LLM token accounting, already uses Rust via PyO3+`tiktoken-rs` — but full compliance + against the new bar, and even whether the control-plane logic itself is in scope of the Rust mandate + at all, is unverified) and Gap 7 (§8's CI integration architecture, plausibly already substantially + met per this repo's own documented conventions, but not audited against every current owner/consumer + relationship in this pass). +- **Verification:** `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` + → 5 passed; `grep -rln "product-goal-directive" tests/` → no matches (still no test pins this file's + prose); `grep -n "�" docs/product-goal-directive.md` → no matches (no corruption introduced). §10's + three new architectural-constraint claims were verified directly against + `.github/workflows/strix.yml` (the `Gate Strix secrets` step's hardcoded `STRIX_MODEL` and its + override-rejecting `case` statement) and `scripts/ci/contextual_orchestrator_review_sidecar.sh` (the + locally generated `ORCHESTRATOR_TOKEN`/bearer-token pattern and the `CONTEXTUAL_ORCHESTRATOR_POOL` + fail-closed validation) before being written, not merely asserted on the strength of the new + directive text. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 Devin Review, round 2: one real §1/§2 self-contradiction, two acknowledged-not-actioned observations + +- **Date:** 2026-09-02. +- **Subject:** a second Devin Review pass on this PR (after the third revision's commit `b3f96812`) + found 3 new items. One `BUG`-severity finding was real and fixed; two `ANALYSIS`-severity + observations are valid but deliberately not actioned in this pass, with reasoning recorded here. + 1. **"Last valid close cannot reach zero" (real, fixed).** §1's new "PR 0개는 병합이나 검증된 + successor의 유효 delta 완전 승계로만 만들고 단순 Close하지 않는다" and §2's four-case close policy + (explicit user instruction / no valid delta / malicious change / verified successor takeover) + conflict for exactly the case where the *last* open PR is legitimately closed under one of §2's + other three cases — §1's shorthand names only "merge or successor takeover" as legitimate paths + to zero, which taken literally would forbid ever reaching zero via a no-valid-delta, malicious, or + user-directed close, directly contradicting §2's own policy one paragraph earlier. **Fix:** added + a reconciliation note (not an edit to either verbatim quote) explaining the correct reading — §1's + constraint targets specifically the disposition of a PR *with a valid, unmerged delta* (merge and + successor-takeover are the two ways named because both preserve that delta, which a bare Close + would silently lose); the other three legitimate close cases don't have that problem (no delta to + lose, nothing worth preserving, or a supervening user instruction), so reaching zero through any + of §2's four legitimate paths is consistent with, not a violation of, §1's actual intent. + 2. **"Obsolete routing guidance remains prominent" (acknowledged, not actioned).** The first + (CodeRabbit, 2026-08-30) note under §8 still describes the superseded "Strix uses + `orchestrator/auto`" framing prominently, even though two later notes in the same section already + mark it superseded and explain why. Devin's suggestion (move the historical guidance to the + doctoring record) is reasonable in isolation, but this file's own established convention — visible + across every prior revision reconciled here — is to leave a superseded note in place with a clear + "superseded by X" marker rather than relocate or delete it, so the in-place reasoning trail (why + the old framing existed, what changed, when) survives for a reader working through the section + top-to-bottom. Moving it to `docs/doctoring/` would break that in-place trail for a reader of + `product-goal-directive.md` itself, who would then need to cross-reference a second file mid- + section. Left as-is; noted here as a considered, not overlooked, decision. + 3. **"Revision history obscures current policy" (acknowledged, not actioned).** A broader structural + observation: current rules now appear in three places (the top preamble's revision-history + paragraphs, in-section commentary notes, and this doctoring file), and a future edit to one could + leave the others stale. Valid, and a natural consequence of three same-day revision passes each + appending its own preamble paragraph and section notes rather than restructuring the file. A full + consolidation (e.g., collapsing the preamble to point at a single canonical changelog rather than + narrating each revision inline) is a legitimate improvement but a materially larger, separate + effort than a review-response fix — restructuring this file's organization is not something to + do reactively inside an unrelated PR round. Not actioned here; worth a dedicated future pass if + the preamble keeps growing at this rate. +- **Verification:** `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` + → 5 passed; `grep -n "�"` → no matches (no corruption). +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 fourth restatement: verified duplicate, no edit made + +- **Date:** 2026-09-02. +- **Subject:** the owner sent the full nine-section directive a fourth time this session, as another + genuine chat-turn message with the same "1. 실행 목표와 지속 Loop..." structure as the prior same-day + restatement (the "third revision," commit `b3f96812`, reconciled earlier in this same session). +- **Method:** rather than assume duplication, did a section-by-section comparison against the then-current + stored text (grep for distinguishing phrases per section, then full manual read-through of every + section). Findings: + - §1, §2, §3, §5, §6, §7: every sentence already present verbatim or in already-reconciled substance. + - §9: the five-domain repo regrouping block and the "immature core" waiting-period sentence both + matched the stored text **character-for-character** — strong evidence this is a genuine repeat send, + not independently re-authored paraphrase. + - §4 and §8 each contained one or two surface reword candidates worth individually checking rather + than waved through: §4's "shadcn/ui는 제품 소유 component source, Storybook은 검증 환경이다" + (explicitly labels shadcn/ui "product-owned" and Storybook "the verification environment") versus + the stored "shadcn/ui는 component source로 Storybook과 대체 관계가 아니다" (component source, not a + Storybook substitute); §4's "측정 성능" (measured performance) versus stored bare "성능"; §8's "LLM + 작업은... CO Agent로 만든다" (LLM work generally) versus stored "LLM이 필요한 테스트는... OpenCode + Agent로 만든다" (tests needing LLM specifically). None of the three appear as literal text in the + stored file (confirmed by `grep -n "측정 성능\|제품 소유\|검증 환경\|LLM 작업은"` — no matches), but + each is a positive restatement/labeling of a relationship or scope already thoroughly established by + surrounding already-stored sentences (Storybook's role as the state-documentation/audit environment + is already spelled out in detail two sentences earlier in the same blockquote; §8's own later + test-time-compute/Fugu-Conductor-TRINITY content already applies to "LLM 사용 소프트웨어" broadly, not + a narrower "tests" scope) — judged non-substantive paraphrase, not a new obligation, consistent with + this file's established policy for condensed re-authored sections. +- **Action:** none. No edit to `docs/product-goal-directive.md`'s quoted sections or notes. This entry + exists so a future pass that receives what looks like the same restatement again can check this record + first rather than re-deriving the same section-by-section comparison from scratch. +- **Not a `/loop` invocation:** unlike some earlier restatements in this session, this one arrived as a + plain chat-turn message with no `/loop` prefix or scheduling instruction — handled identically to a + `/loop`-delivered restatement per this file's own directive-reconciliation convention, which does not + distinguish delivery mechanism. + +## 2026-09-02 Devin Review, round 3: two real findings (whitespace, §10 owner-authorization gap), one real precision correction to this session's own prior verification note + +- **Date:** 2026-09-02. +- **Subject:** a third Devin Review pass on this PR (after commit `77f16947`, the second merge from + `main`) found 3 new items — 1 `ANALYSIS`-severity, 2 `BUG`-severity — all verified against source + before acting, and all three real. + 1. **"Whitespace validation fails" (real, fixed).** `git diff --check origin/main` flagged trailing + whitespace on `docs/product-goal-directive.md:161` (inside this session's own §1/§2 reconciliation + note from the round-2 fix) and `docs/product-technical-gap-baseline.md:2684` (inside an + already-merged `main`-side paragraph that this PR's diff still carries against its older base). + **Fix:** stripped trailing whitespace from both exact lines with a scoped `sed`, re-verified + `git diff --check` clean on all three touched files. + 2. **"Owner authorization remains contradictory" (real, fixed).** `AGENTS.md` and ADR-0003's + 2026-08-31 correction both still say the *original 2026-08-30 implementation* (the commit that + hardcoded `strix.yml` to `orchestrator/free`) was an unreviewed, non-owner-authorized agent action, + and that the resulting availability risk is still open/unreviewed with reversion to + `orchestrator/auto` explicitly "not foreclosed." Read next to §10 — which presents + `orchestrator/free` pinning as owner-directed — that reads as a flat contradiction without further + context. **Fix:** added a reconciliation note distinguishing two separate facts that don't conflict + once kept apart: the 2026-08-30 *implementation* event (unauthorized, unchanged by this item) versus + §10 itself, which *is* a separate, later, genuine owner directive (issued via `/loop` on + 2026-09-01) authorizing the CI-workflow *policy* going forward — but that policy authorization is + not the same as, and does not retroactively supply, the specific documented risk-acceptance + ADR-0003 says is still missing. Both records stay true simultaneously: the pin is owner-authorized + as CI policy, and the specific availability risk it carries remains open and unreviewed. + 3. **"Workflow-only token claim is false" (real precision correction to this session's own prior + verification note, not the user's verbatim directive text).** This session's own round-2 doctoring + entry ("Devin Review round 2") verified §10's Addition item (2) — "workflow는 provider·model· + group명·유료 fallback을 지정하지 않고 gateway token만 쓴다" — by pointing at `strix.yml`'s hardcoded + `STRIX_MODEL` and its `case`-statement override rejection, and summarized this as "the workflow has + no live path to specify a different provider, model, or group." That summary sentence overstated + it: `strix.yml:732-749`'s `Prepare Strix model input file` step does write the literal string + `orchestrator/free` into `STRIX_LLM_FILE` and pass that file to Strix alongside the gateway token — + a group/model identifier genuinely is communicated, just always the one hardcoded constant, never a + live choice. **Fix:** corrected the verification note's own wording to say the workflow has no live + path to *choose* a different provider/model/group/paid-fallback, rather than implying no + model/group identifier is ever communicated at all. Note this is a fix to **this session's own + added commentary**, not to the user's verbatim `>` blockquote text (§10's own quoted lines were + never touched). +- **Verification:** `git diff --check origin/main -- docs/product-goal-directive.md + docs/product-technical-gap-baseline.md` → exit 0 (clean); `grep -n "�" docs/product-goal-directive.md` + → no matches; `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` → 5 + passed. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 Devin Review, round 4: escalated re-review of round 3's own §10 fix, one real gap tightened + +- **Date:** 2026-09-02. +- **Subject:** Devin re-reviewed round 3's §10 owner-authorization reconciliation note (commit + `537c3872`) and escalated it to 🔴 (highest severity in this session's experience with this + reviewer): "Authorized routing can be reverted" — the note, as written, quoted ADR-0003's "reverting + to `orchestrator/auto`... is not foreclosed" sentence and said that framing was "unchanged by this + item," which — read in isolation from the sentence right after it — could be misread as current, + standing license for an agent to revert the owner's own binding §10 CI pin on its own initiative. +- **Assessment:** the note's own very next sentence already said reversion would require "§10 would + need updating to match, not the other way around," so the substantive guardrail was present — but the + finding is right that the paragraph's internal ordering let the "not foreclosed" quote read as the + operative instruction if a reader stopped there, exactly the kind of ambiguity that produced the + original 2026-08-30 incident this whole note exists to prevent a repeat of. Real clarity gap, fixed. +- **Fix:** rewrote the paragraph to lead with an explicit, unambiguous prohibition — "No agent may treat + ADR-0003's... sentence as standing authorization to revert the CI pin today" — and to explain *why*: + that ADR-0003 sentence describes the risk-acceptance question's unreviewed status as of 2026-08-31, + written *before* §10 existed; §10 is the later, explicit, binding instruction; the only legitimate + path to `orchestrator/auto` is a **new owner decision updating §10 itself**, never an agent's own + reading of "not foreclosed" in isolation. Closes with the same "both records true at once" framing as + round 3, now preceded by the explicit guardrail rather than following the ambiguous quote unguarded. +- **Verification:** `git diff --check origin/main -- docs/product-goal-directive.md` → exit 0; + `grep -n "�" docs/product-goal-directive.md` → no matches; + `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` → 5 passed. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 Devin Review, round 5: one real ID-collision bug fixed, one real clarity gap tightened, one analysis finding verified false and not acted on + +- **Date:** 2026-09-02, after this PR's second merge from `main` (commit `c16d712c`, pulling in the + `#1672` Noema single-request work and 10 other commits). +- **Subject:** a fifth Devin Review pass found 3 new items: 1 `BUG` (`based_on_repo_rules: true`), + 2 `ANALYSIS`. All three checked against live source before acting, per this session's standing + verify-before-acting discipline. +- **Finding 1 (BUG, real, fixed) — "New gaps have colliding identifiers."** `docs/product-technical-gap-baseline.md` + had accumulated seven narrative product-gap entries across this PR's own commits, labeled "Gap 1" + through "Gap 7" — a distinct, informal numbering scheme that collides on sight with this same file's + canonical `## 3. Gap register` table, which already uses `G-01` through `G-16` as the one ID space + every PR is instructed to cite (`"이 문서의 Gap ID를 연결한다"`, line 2523/2534). Confirmed via + `git diff origin/main...HEAD` that all seven "Gap N" labels were introduced by this branch's own + commits (none exist on `main`), so this was this PR's own defect to fix, not a pre-existing one to + merely flag. **Fix:** renamed all seven in place to continue the canonical sequence — `Gap 1`→`G-17` + (E2E load-test gate), `Gap 2`→`G-18` (admin per-model LLM timeout), `Gap 3`→`G-19` (i18n ledger), + `Gap 4`→`G-20` (ontology-pipeline split), `Gap 5`→`G-21` (master-context catalog gap), `Gap 6`→`G-22` + (contextual-orchestrator Python-vs-Rust audit), `Gap 7`→`G-23` (§8 CI-architecture audit) — updated + every cross-reference (the "Gap 3, above" and "Gap 4 and Gap 5 are the same..." sentences), and added + one compact row per new ID to the `## 3. Gap register` table itself (pointing to the fuller narrative + entries below for detail), so the register — the thing PRs are actually told to cite — is complete + rather than seven items existing only in prose with no register row. +- **Finding 2 (ANALYSIS, verified false as stated, but a real underlying clarity gap fixed) — + "Revision count is stale."** Anchored on the status line's "revised 2026-09-01, 2026-09-02 (twice, + same day)." Checked this against every dated heading in this file: `2026-09-01 revision` (substantive, + 3 sections), `2026-09-02 revision` (substantive, 5 sections), `2026-09-02 third revision` (substantive, + 8 sections — labeled "third" because it is the third substantive revision *overall*, counting + 2026-08-30's original as the baseline), and `2026-09-02 fourth restatement` (verified, in its own + entry above with a full section-by-section comparison, to be a **non-substantive duplicate** — no + edit was made to `product-goal-directive.md` for it). Arithmetic: 1 (09-01) + 2 (09-02) = 3 + substantive revisions total, which is exactly what "revised 2026-09-01, 2026-09-02 (twice, same day)" + already states — so the specific claim "the history documents a third substantive revision" not + reflected in the status line is **false**; the third one (the "third revision" heading) *is* one of + the two 09-02 occurrences the status line already counts. Not acted on as stated. However, the + underlying confusion is real and worth preventing: a heading reading "third revision (second same-day + chat message)" sitting next to a status line reading "twice, same day" invites exactly this + misreading (is "third" a same-day count or an overall count?) for the next reviewer, human or bot. + **Fix (clarity, not correction):** reworded the status line to spell out the count explicitly ("plus + three substantive revisions since — 2026-09-01 (one), 2026-09-02 (two, same day; the second of these + is labeled 'third revision' in the doctoring file because it is the third substantive revision + overall, not a third same-day one)") and to state plainly that the fourth same-day restatement was + compared and found non-substantive, so a future reader (or reviewer) never has to redo this exact + arithmetic check. +- **Finding 3 (ANALYSIS, real, fixed) — "Load target lacks a timing boundary."** The new `G-17` entry's + "every page's p95 end-to-end processing time must be ≤ 20ms" never stated what interval that spans. + Confirmed the ambiguity is real and consequential: a server request-received-to-response-sent + measurement, a browser navigation-start-to-load-event measurement, and an interaction-to-next-paint + measurement are all plausible readings of "processing time" and would yield materially different + numbers for the same page — and k6's own default HTTP-duration metric only covers the first of the + three, silently excluding client-side render/hydration cost if that boundary were assumed without + being stated. This ambiguity lives in this file's own explanatory prose (not the directive's verbatim + quote elsewhere, which this file's governance clause forbids rewording), so it was this session's own + gap to fix. **Fix:** added a sentence to `G-17` naming the three candidate boundaries, noting k6's + default metric only covers the transport leg, and instructing that a future implementing k6 suite + must pick and document one explicit boundary (pairing k6 with a browser-timing tool if client-side + work is in scope) so "meets the gate" has one fixed meaning across every page and re-verification. +- **Verification:** `git diff --check origin/main -- docs/product-goal-directive.md + docs/product-technical-gap-baseline.md` → exit 0; `grep -n "�" docs/product-goal-directive.md + docs/product-technical-gap-baseline.md` → no matches; `grep -n "Gap [0-9]" + docs/product-technical-gap-baseline.md` → no matches (confirms no collision-prone label survives); + `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` → 5 passed. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 Devin Review, round 6: one real cross-repo-reference-format bug fixed, one real untracked security gap recorded (not fixed by rewording the owner's verbatim text) + +- **Date:** 2026-09-02. +- **Subject:** a sixth Devin Review pass found 2 new items: 1 `ANALYSIS` (repository-reference format), + 1 `SEC` (security). Both checked against live source and the org's own binding convention before + acting. +- **Finding 1 (ANALYSIS, partially real) — "Repository references lack full ownership."** Anchored on + `docs/product-technical-gap-baseline.md`'s new `.github#1659` reference. Checked + `docs/CWL-MASTER-CONTEXT.md` §7's actual rule: "Cross-repo references must be `owner/repo#num`... **Same-repo may use `#num`**." `.github#1659` is a same-repo reference (this file lives in `.github`), so + it already satisfies the rule as written — Devin's framing that *all* references need the owner + prefix is not what the convention says. **However**, checking the same diff for genuine cross-repo + references surfaced a real instance the finding's title correctly describes even if its example + didn't: two newly-added bare `naruon#1486` references (this file lives in `.github`, so a reference to + a `naruon` PR *is* cross-repo and needs the full form) — confirmed via + `git diff origin/main...HEAD` that both are new to this branch (two other bare `naruon#...` mentions + in the file predate this branch and are out of this pass's scope). **Fix:** qualified both new + references to `ContextualWisdomLab/naruon#1486`. The `.github#1659` same-repo reference was left as-is + since it already complies. +- **Finding 2 (SEC, real, recorded not rewritten) — "Product logins collect identity passwords."** + Anchored on `docs/product-goal-directive.md`§4's verbatim owner blockquote (line 183): "Keyverse는 + 인증 backend로 유지하되(Direct Grant/ROPC 또는 Keycloak REST API), 로그인·가입·복구는 제품 자체 + form으로 만든다." The underlying technical claim is correct and well-established: OAuth2 ROPC/"Direct + Grant" by definition has the client application itself collect and forward the user's raw password, + unlike a redirect-based Authorization Code flow where only the identity provider's own hosted page + ever sees it — precisely the isolation property RFC 6819/the OAuth 2.0 Security BCP cite as the + reason ROPC is discouraged. Confirmed via `grep -rln "ROPC\|Direct Grant\|passwordless" docs/adr/` + and a grep of this file that this trade-off was genuinely untracked anywhere in this repo — a real + gap, not a duplicate. **Not fixed by editing the quote:** this sentence is the owner's own explicit, + deliberate architecture choice (naming both ROPC and the Keycloak REST API specifically, almost + certainly *because* both allow the product-branded, non-redirected login UI the same sentence + mandates, despite the well-known trade-off) — rewording it would substitute this session's judgment + for an explicit owner decision, which this file's own governance clause and this PR's established + practice throughout forbid. **Recorded instead:** added `G-24` to the gap register plus a full + narrative entry in `docs/product-technical-gap-baseline.md`, naming the trade-off, confirming it was + untracked, and directing a future Keyverse-integration ADR to make an explicit reviewed decision + (accept with compensating controls — TLS, no credential logging/storage beyond the immediate + exchange, product-side rate-limit/lockout — or revise the pattern) rather than leaving the trade-off + implicit. +- **Verification (this round):** `git diff HEAD -- docs/product-goal-directive.md` → empty at the time + of this round's own edit, confirming this round's change (adding G-24) touched only + `docs/product-technical-gap-baseline.md` and did not modify `docs/product-goal-directive.md` — a claim + about this round's edit scope, not a comprehensive proof that the §4 blockquote has stayed + byte-for-byte identical to the owner's original text across this PR's entire commit history (which + has, by design, added new sentences to it in earlier, individually-verified-against-the-owner's-text + rounds); `git diff --check origin/main -- docs/product-technical-gap-baseline.md` → exit 0; + `grep -n "�" docs/product-technical-gap-baseline.md` → no matches; + `grep -rln "ROPC\|Direct Grant\|passwordless" docs/adr/` → no matches (confirms G-24 was genuinely new); + `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` → 5 passed. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 Devin Review, round 7: one real technical error in this session's own G-24 compensating-control suggestion fixed, one real verification-claim overreach corrected + +- **Date:** 2026-09-02, after round 6's push (`fcad134f`). +- **Subject:** a seventh Devin Review pass found 2 new items: 1 `SEC`, 1 `ANALYSIS`. Both about this + session's own prior-round work, not the owner's directive text. +- **Finding 1 (SEC, real, fixed) — "Embedded webview defeats OAuth isolation."** Round 6's `G-24` entry + suggested "a PKCE-based Authorization Code flow inside an embedded/native webview" as a lower-risk + alternative to ROPC. This conflates two orthogonal OAuth protections: PKCE protects the *authorization + code exchange* from interception/replay by a different app on the same device; it says nothing about + who can observe the *login page itself*. An embedded webview is rendered inside, and fully inspectable + by, the hosting product's own process — cookies, DOM, injected JS, form field values are all reachable + by the product regardless of PKCE — so it provides **no isolation improvement over ROPC at all**. This + is precisely why RFC 8252 ("OAuth 2.0 for Native Apps") mandates the external user agent (system + browser, or an OS-mediated in-app-browser-tab construct such as `SFSafariViewController`/ + `ASWebAuthenticationSession` on iOS or Chrome Custom Tabs on Android — a separate, product-inaccessible + process/cookie jar) rather than an app-embedded webview. **Fix:** removed the embedded-webview + suggestion from both the `G-24` register row and its narrative entry; added a correction paragraph to + the narrative explaining the error (PKCE ≠ webview isolation) and stating the technically correct + alternative, if one is wanted: Authorization Code + PKCE *via the external user agent*, never an + embedded webview. +- **Finding 2 (ANALYSIS, real, fixed) — "Verification cannot prove unchanged text."** Round 6's + verification line claimed `git diff docs/product-goal-directive.md` → empty "confirms the verbatim + blockquote was not touched," phrased as an unqualified claim. A bare `git diff` only compares the + working tree against the index/HEAD at the moment it's run — it proves that *round's own edit* made no + further change to the file, not that the blockquote has been byte-for-byte stable across this PR's + entire commit history (which it has not been, by design — earlier rounds added new sentences to it, + each individually verified against the owner's supplied text at the time). **Fix:** reworded the round + 6 verification entry above to scope the claim correctly to "this round's own edit" rather than + implying a whole-PR-history proof. +- **Verification:** `grep -n "PKCE\|embedded" docs/product-technical-gap-baseline.md` → the word + "embedded" still appears in both the register row and the narrative — that grep alone does not + distinguish *recommending* embedded webview (the bug) from *warning against* it (the fix), so its + presence is not itself informative; what changed is what surrounds it: the register row's remaining + mention now reads "embedded webview는 PKCE 여부와 무관하게 격리를 제공하지 않으므로... 대안은 반드시 + external user agent... 기반이어야 한다" (a warning, not a recommendation), and the narrative's mentions + are inside the correction paragraph explaining the error. Manually re-read both after the edit to + confirm neither still recommends it. `git diff --check origin/main -- docs/product-technical-gap-baseline.md docs/doctoring/product-goal-directive.md` + → exit 0; `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` → 5 passed. +- **PR:** `ContextualWisdomLab/.github#1659`. + +## 2026-09-02 Devin Review, round 8: one real self-verification-wording error corrected + +- **Date:** 2026-09-02, after round 7's push (`9b7e059c`). +- **Subject:** an eighth Devin Review pass found 1 `ANALYSIS` item, again about this session's own + verification wording rather than the tracked content itself. +- **Finding (real, fixed) — "Verification misstates webview references."** Round 7's verification line + claimed `grep -n "PKCE\|embedded" docs/product-technical-gap-baseline.md` showed the embedded-webview + suggestion "no longer appears in either the register row or narrative (only the correction paragraph + mentions 'embedded')." Checked directly: `grep -n "embedded" docs/product-technical-gap-baseline.md` + shows the word still present in the `G-24` register row itself (line 104), not only the narrative — + the claim was factually wrong about *where* the word appears, even though the underlying fix was + correct (the register row's remaining mention is now a warning against embedded webview, not a + recommendation for it, so the content is fine; only the doctoring's description of the grep result was + inaccurate). +- **Fix:** reworded the round 7 verification entry above to state the true grep result (the word + "embedded" appears in both places) and explain why a bare keyword grep can't distinguish + recommending-it from warning-against-it — that distinction requires reading the surrounding sentence, + which is what actually matters and what was actually checked. +- **Verification:** `grep -n "embedded" docs/product-technical-gap-baseline.md` → confirms present in + both the register row (line 104) and the narrative correction (lines 2925-2940ish); manually + re-read both to confirm neither recommends embedded webview as a solution; + `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` → 5 passed. +- **PR:** `ContextualWisdomLab/.github#1659`. diff --git a/docs/product-goal-directive.md b/docs/product-goal-directive.md index c76c4226e4..454ce75d1b 100644 --- a/docs/product-goal-directive.md +++ b/docs/product-goal-directive.md @@ -1,8 +1,111 @@ # Product goal directive — autonomous PR/merge/development loop -**Status:** active standing directive · **Owner intent recorded:** 2026-08-30 · **Scope:** the full -ContextualWisdomLab ecosystem (every repo an agent can reach from this org, leveraged in order of -product responsibility / reuse boundary / docs / implementation / consumption — not by name). +**Status:** active standing directive · **Owner intent recorded:** original 2026-08-30, plus three +substantive revisions since — 2026-09-01 (one), 2026-09-02 (two, same day; the second of these is +labeled "third revision" in `docs/doctoring/product-goal-directive.md` because it is the third +substantive revision overall, not a third same-day one). A fourth same-day restatement on 2026-09-02 +was compared section-by-section against the stored text and found to be a verified duplicate with no +new obligation (see doctoring's "fourth restatement" entry) — it is not counted as a revision here. · +**Scope:** the full ContextualWisdomLab ecosystem (every repo an agent can reach from +this org, leveraged in order of product responsibility / reuse boundary / docs / implementation / +consumption — not by name). + +**2026-09-01 revision:** the owner re-issued the full directive via a `/loop` invocation. Sections 1, 2, +4, 5, 6, and 9 were re-authored in largely the same words (cosmetic rephrasing only — no new +obligation); this file's existing verbatim text for those sections already carries the same +substance and was left as-is to avoid needless churn. Three sections gained genuinely new, +substantive requirements not previously recorded here, and were updated in place (see +`docs/doctoring/product-goal-directive.md` for the full record): §3 gained an explicit +decision-traceability standard (write every decision so a reader with no context, or the author +having forgotten it, can reconstruct the problem/constraints/alternatives/reasons/risks/expected +effects/follow-ups, with vivid concrete scenarios and links to exact-head/logs/issues/PRs/ADRs/ +experiments); §7 gained a concrete, testable E2E acceptance criterion (p95 ≤ 20ms per page, every +page, re-verify after removing any bottleneck); §8 gained two new principles — never hardcode an +LLM provider *group* name in code/config/tests/routing (treat it as a display alias only, and drive +selection/fallback from auto-discovered model characteristics instead), and never impose a uniform +hardcoded LLM request timeout (default unlimited/`null`; timeouts are an admin-configurable, +audited, per-model setting with units/priority/inheritance, never a bare elapsed-time cutoff on an +in-progress reasoning/streaming/tool-call turn). A follow-up `/loop` invocation the same day added a +new §10, crystallizing an already-implemented decision (Strix pinned to `orchestrator/free`, +previously recorded only in a §8 annotation) into the primary numbered directive. + +**2026-09-02 revision:** the owner re-issued the full directive again, this time in a visibly +condensed form for §1/§3/§6/§8 (same substance, shorter wording — left as-is, same policy as +2026-09-01) but substantially *expanded* for §2, §4, §5, §7, and §9 with genuinely new, concrete +obligations not previously recorded here. Updated in place; see +`docs/doctoring/product-goal-directive.md` for the full per-section record. In summary: §2 gained an +explicit "immature core" protocol (never duplicate/bypass/exclude an immature dependency in the +consumer — build the missing RED test/contract/feature/docs/release in the *owner* repo through its +own CI, then consume a versioned release; excluding a dependency via ADR is reserved for a genuinely +wrong boundary or no shared need) and a new reference tool for Korean-language editing +(epoko77-ai/im-not-ai, preserving meaning/facts/figures/proper nouns). §4 gained a concrete i18n +architecture mandate (eight named languages; CJK/width/wrap/font-fallback/locale-format testing +per language in Storybook/E2E; the translation ledger is a **versioned DB resource**, never static +files or a JS bundle — runtime fetches only the current screen's keys with caching, the browser never +receives the whole catalog, and no SPA assumption; stand up a dedicated management repo — translation +review/approval/deploy/rollback API + admin UI — if no shared one exists yet), a UI-composition +principle (all UI is reusable objects; pages are compositions of them), an explicit shadcn/ui-vs- +Storybook clarification (shadcn/ui is a component *source*, not a Storybook substitute), a frontend +stack-flexibility principle (no fixed stack; React/Vite/shadcn/ui/jQuery 4/etc. are fine when they +meet security/maintainability/standards/accessibility/performance), and a specific Keyverse +integration pattern (Keyverse stays the auth *backend* — Direct Grant/ROPC or the Keycloak REST API — +but login/signup/recovery are the product's own forms, not a Keyverse-hosted page). §5 gained a +concrete ontology-pipeline repo-responsibility split (ConceptWeave owns the +observe→discover→propose→align→validate→review→publish pipeline and semantic release; +semantic-data-portal owns catalog/governance/consumption; context-graph-contracts owns interop +contracts; enterprise-architecture-core owns the Context Map and cross-cutting decisions — domain +truth/Ubiquitous Language itself stays with the product owner), an immutable-release data contract +for ontology concepts (evidence/provenance/validity/confidence/status/deprecation/locale label +required on every released concept/relation/dimension/measure/mapping), a consumer-boundary +prohibition (released API/contract/ACL only — no file copies, no cross-service SQL, no unapproved +publication), and an explicit separation between the UI translation ledger (§4) and the ontology +label ledger (§5) — the two must never share a store. §7 gained two anti-gaming clauses for the +existing p95≤20ms criterion (never satisfy it by shrinking the sample, excluding measurements, or an +unrealistic cache warm-up; when the bottleneck is the JS bundle/heap/DOM/hydration/main +thread/GC, replace the dependency or frontend stack rather than accepting the ceiling) and reaffirms +profiling algorithm/query/I/O/rendering first, moving to a Rust-first hot path only when the +runtime/language/framework itself is the proven cause. §9's repository catalog roughly +tripled in size and gained explicit per-repo responsibility statements for +`.github`, `enterprise-architecture-core`, `context-graph-contracts`, `ConceptWeave`, +`semantic-data-portal`, `noema`, `EgressWeave`, `OriginWeave`, `pingora-gateway`, +`quarantine-sandbox-runtime`, `pg-llm-batch`, `EmbedRelay`, `inkspan`, `DiagramWeave`, +`mhtml-etl-gateway`, `appguardrail`, plus an explicit "domain product/composition consumer, not core" +classification for `naruon`, `LineageWeave`, `psychometrics-commons`, `disksage`, `PolicyWeave`, +`CalendarWeave`, and `supply-chain-control-plane` — see the reconciliation note under §9 for which of +these this session could and could not independently cross-check against +`docs/CWL-MASTER-CONTEXT.md`. §8's restatement mentions the `orchestrator/free` pin again, but inline +inside §8's general body rather than as the separately-qualified §10 item — see the note added below +§10 for why that does not reopen or loosen the existing, evidence-verified CI-workflow scope +qualifier. + +**2026-09-02 second revision (same day):** the owner re-issued the full directive a third time overall +(second time this day), again as a genuine chat-turn message, titled "아래는 일반 지침" like the prior +same-day restatement. §3 and §4 were re-authored in condensed form with no new obligation detected +(left as-is); every other section gained genuinely new content, updated in place — see +`docs/doctoring/product-goal-directive.md` for the full per-section record. In summary: §1 gained an +explicit constraint on what "0 open PRs" may legitimately mean (merge or a verified successor's full +delta takeover only, never a bare close). §2 gained a detailed six-category PR close/repair taxonomy +(single-writer/DDD violations, wrong base/conflicts, ADR number collisions, premature Accepted status, +unprotected dependencies, missing test/fixture/contract are all repair findings, never close reasons) +with an explicit repair procedure (downgrade to Draft/Proposed, non-force restack/retarget) and a +four-case-only close policy. §5 widened the two-or-more-word naming rule from DB objects specifically +to essentially every named code entity, plus an explicit boundary-conversion rule for +language/framework/external-contract naming conventions. §6 sharpened the Rust-first mandate into an +explicit Python-disfavored rule with one narrow, ADR-tracked exception. §7 added "rendering" to the +list of things to replace when the JS bundle/DOM/GC is the bottleneck. §8 gained a "consume via +released API/client/schema" consumption pattern plus a detailed CI integration architecture (`.github` +reusable-workflow-plus-thin-caller composition, exact-SHA verification across build/contract/E2E/ +model-behavior/security/SBOM/provenance, owner-side RED→fix→GREEN→release, and an explicit ban on +mutable-head/branch-URL/cross-repo-source/workflow duplication). §9 gained a definitional framing of +what "core foundation" actually means (a selective, canonically-owned, versioned-contract-providing +control plane — never a default install; role/maturity confirmed from the protected branch, not an +open PR's own claims), a five-domain regrouping of the existing repo catalog, and a concrete +elaboration of the "immature core" waiting-period mechanics (port/ACL/feature-flag/test-double +boundary protection; never read the owner's raw source/DB/temp branch directly). §10's existing pin +gained three specific architectural constraints, each verified against current `strix.yml`/sidecar +source rather than merely restated (free-pool discovery/routing/fallback stays inside CO; the workflow +itself has no live path to specify a provider/model/group and only ever sees a local gateway token; +missing capability fails closed with no paid bypass). ## Why this file exists @@ -21,29 +124,81 @@ GitHub Project #1, `docs/product-technical-gap-baseline.md`, or `docs/agent-gith Where this directive and those documents conflict, resolve the conflict and update whichever document is wrong — do not silently pick one. -The directive is recorded verbatim (Korean, as authored) in the nine sections below, each given a short +The directive is recorded verbatim (Korean, as authored) in the ten sections below, each given a short English heading for navigability. Do not paraphrase or shorten these sections when copying them elsewhere; link to this file instead. ## 1. Execution goal and continuous loop -> 실행 목표와 지속 Loop 열린 PR마다 별도 중간 보고 없이 리뷰 확인→수정→GitHub Checks 재검증→병합→다음 개발을 반복하라. PRD를 읽고 Loop·Goal을 자율 생성·수정·제거해 PR을 병합 또는 0개로 만들며 상용화하라. 200억 달러에 판매할 자신이 있을 품질과 구매자가 체감할 제품 Gap 해소가 목표다. ADR·리서치·현행 데이터·PR로 기능 명세·PRD·TRD·UML·Gap·조치 상태를 도출해 docs/product-technical-gap-baseline.md에 갱신하라. 한 시간 간격으로 예약하고 메시지도 개선·갱신하라. PR·Issues 소진 후에도 제품 Gap 개발과 병합 Loop를 계속한다. 내가 온전히 소유한 ContextualWisdomLab 저장소를 레버리지 순으로 연계해 PR 병합·추가와 Connector 추가·수정 등 Ecosystem을 구축하라. Ecosystem 전 라이브러리 PRD를 숙지하고 조직·저장소명 대소문자를 지킨다. 리뷰·Checks 대기는 Blocker가 아니며, 실패 원인·수정·재실행 필요에 즉시 대응하며 안전한 작업을 계속한다. 결과 보고에 멈추지 말고 다음 Loop로 이동하라. 저장소는 이름이 아니라 제품 책임·재사용 경계·문서·구현·소비 저장소를 대조해 선택한다. ADR·Goal을 수시로 갱신하고 Goal 수정 불가 시 Loop를 갱신한다. +> 실행 목표와 지속 Loop 열린 PR마다 별도 중간 보고 없이 리뷰 확인→수정→GitHub Checks 재검증→병합→다음 개발을 반복하라. PRD를 읽고 Loop·Goal을 자율 생성·수정·제거해 PR을 병합 또는 0개로 만들며 상용화하라. PR 0개는 병합이나 검증된 successor의 유효 delta 완전 승계로만 만들고 단순 Close하지 않는다. 200억 달러에 판매할 자신이 있을 품질과 구매자가 체감할 제품 Gap 해소가 목표다. ADR·리서치·현행 데이터·PR로 기능 명세·PRD·TRD·UML·Gap·조치 상태를 도출해 docs/product-technical-gap-baseline.md에 갱신하라. 한 시간 간격으로 예약하고 메시지도 개선·갱신하라. PR·Issues 소진 후에도 제품 Gap 개발과 병합 Loop를 계속한다. 내가 온전히 소유한 ContextualWisdomLab 저장소를 레버리지 순으로 연계해 PR 병합·추가와 Connector 추가·수정 등 Ecosystem을 구축하라. Ecosystem 전 라이브러리 PRD를 숙지하고 조직·저장소명 대소문자를 지킨다. 리뷰·Checks 대기는 Blocker가 아니며, 실패 원인·수정·재실행 필요에 즉시 대응하며 안전한 작업을 계속한다. 결과 보고에 멈추지 말고 다음 Loop로 이동하라. 저장소는 이름이 아니라 제품 책임·재사용 경계·문서·구현·소비 저장소를 대조해 선택한다. ADR·Goal을 수시로 갱신하고 Goal 수정 불가 시 Loop를 갱신한다. ## 2. Concurrent operation, PR handling, and root-cause fixes -> 동시 작업·PR 운영·근본 수정 원격 Agent의 동시 Commit·Push를 경합으로 단정해 Force Push·중단하지 말고 변경 취지·이유를 확인해 이어간다. Commit·Push 전 병합 여부를 확인하고 삭제 근거를 남긴다. Self-modifying/Source-fix Workflow는 목적 달성 후 삭제하고 잔존 시 관찰·제거한다. 가능한 PR은 Stack하고 not-merge-ready를 merge-ready로 전환한다. 유관 프로젝트 원인이 엮이면 함께 처리하고 Stacked PR을 중앙 OpenCode Agent가 리뷰하지 않으면 ContextualWisdomLab/.github를 수정한다. Agent 간 대화·Spawn을 활용한다. 수동 해법은 모두 코드·설정에 반영한다. PYTHONPATH=. 누락은 설정하고 GitHub Actions·런타임 오류는 로그·Root Cause Analysis로 제거한다. 전체 GitHub Checks 실패를 확인·수정한다. ContextualWisdomLab 내부 라이브러리 문제라면 원시 공급자 오류까지 고쳐 PR한다. 개발 프로세스에 https://github.com/DietrichGebert/ponytail 및 https://github.com/obra/superpowers 를 사용하되 superpowers의 "무조건 질문" 규칙은 무시한다. https://github.com/tirth8205/code-review-graph 와 https://github.com/colbymchenry/codegraph 도 사용하고 인덱싱은 스스로 수행한다. 이는 명시적으로 허가됐다. +> 동시 작업·PR 운영·근본 수정 원격 Agent의 동시 Commit·Push를 경합으로 단정해 Force Push·중단하지 말고 변경 취지·이유를 확인해 이어간다. Commit·Push 전 병합 여부를 확인하고 삭제 근거를 남긴다. Self-modifying/Source-fix Workflow는 목적 달성 후 삭제하고 잔존 시 관찰·제거한다. 가능한 PR은 Stack하고 not-merge-ready를 merge-ready로 전환한다. 유관 프로젝트 원인이 엮이면 함께 처리하고 Stacked PR을 중앙 OpenCode Agent가 리뷰하지 않으면 ContextualWisdomLab/.github를 수정한다. Agent 간 대화·Spawn을 활용한다. single-writer·DDD 위반, 잘못된 base·충돌, ADR 번호 충돌, 성급한 Accepted, 미보호 dependency, 누락된 test·fixture·contract는 Close가 아닌 repair finding이다. Draft·Proposed로 낮추고 owner stack에 non-force restack·retarget해 수리한다. single-writer는 delta 폐기가 아닌 통합이다. 직접 못 고치면 successor가 delta를 완전 승계하고 predecessor를 잇는다. foundation 미착지 시 prerequisite를 완성하며 PR은 유지한다. 오폐쇄는 reopen·successor로 복구한다. Close는 사용자 명시, 유효 delta 없음, 악성 변경, 완전 승계에만 허용하며 표시는 종결이 아니다. 수동 해법은 모두 코드·설정에 반영한다. PYTHONPATH=. 누락은 설정하고 GitHub Actions·런타임 오류는 로그·Root Cause Analysis로 제거한다. 전체 GitHub Checks 실패를 확인·수정한다. ContextualWisdomLab 내부 라이브러리 문제라면 원시 공급자 오류까지 고쳐 PR한다. 필요한 core가 미성숙해도 consumer에서 복제·우회·제외하지 말고 owner에 RED test·계약·기능·문서·release를 개발해 통합 CI GREEN 후 versioned release로 연결한다. 경계가 틀리거나 공통 수요가 없을 때만 ADR 근거로 제외한다. 개발 프로세스에 https://github.com/DietrichGebert/ponytail 및 https://github.com/obra/superpowers 를 사용하되 superpowers의 "무조건 질문" 규칙은 무시한다. https://github.com/tirth8205/code-review-graph 와 https://github.com/colbymchenry/codegraph 도 사용하고 인덱싱은 스스로 수행한다. 이는 명시적으로 허가됐다. 한국어 문구·문서·번역은 https://github.com/epoko77-ai/im-not-ai로 의미·사실·수치·고유명사를 보존하며 윤문한다. + +**Addition (2026-09-02, second revision):** a detailed PR close/repair taxonomy not previously spelled +out in this file. It names six specific defect classes that must be treated as **repair findings, not +close reasons** — a single-writer or DDD-boundary violation, a wrong base or merge conflict, a +colliding ADR number, a review that Accepted prematurely, an unprotected dependency, or a missing +test/fixture/contract — and prescribes the repair path: downgrade the PR to Draft/Proposed and +non-force restack/retarget it onto the owner's stack (never force-push over it). It states single-writer +resolution explicitly as **integration of deltas, not discarding them**: when a PR can't be fixed +directly, a successor PR must fully inherit its delta and continue the predecessor's work; when a +foundation dependency hasn't landed yet, the prerequisite gets completed while the PR itself stays +open; a wrongful close gets recovered via reopen or a successor. Close itself is narrowed to exactly +four legitimate cases — explicit user instruction, no valid delta exists, a malicious change, or a +verified successor's full takeover — with an explicit warning that a "closed" label is not itself +closure (i.e., a close still needs one of those four justifications behind it, not just the state +change). This directly reinforces and gives specific mechanics to §1's new "PR 0개는... 단순 Close하지 +않는다" sentence above (both added in this same revision) — §1 states the outcome constraint (reaching +zero open PRs must go through merge or verified successor takeover, never a bare close), and this +addition provides the operational taxonomy and repair procedure for getting there. + +**Reconciliation (flagged by Devin Review on this PR, 2026-09-02):** read too literally, §1's "병합이나 +검증된 successor의 유효 delta 완전 승계로만 만들고 단순 Close하지 않는다" and this section's four-case +close policy conflict for exactly one case: if the **last** open PR is legitimately closed under §2's +"유효 delta 없음" (no valid delta), "악성 변경" (malicious change), or "사용자 명시" (explicit user +instruction) case, that close also reaches zero open PRs — a path §1's shorthand names only two ways +to reach ("병합이나... 완전 승계로만"), taken word-for-word forbidding this. That reading cannot be the +intent: it would force keeping open a PR with no valid delta, or one that's malicious, or one the user +explicitly told the agent to close, purely to avoid the open-PR count hitting zero — directly +contradicting the four-case close policy this same section states one paragraph earlier. The correct +reading, consistent with both sentences and with why §1 names *merge or successor takeover* +specifically: §1's constraint targets the disposition of a PR that **has a valid, unmerged delta** — +merge and successor-takeover are the two ways named because both are the ways to preserve that delta, +which is exactly what a bare Close would silently lose. The other three legitimate close cases in this +section by construction do not have that problem: "no valid delta" has nothing to preserve, "malicious +change" has nothing worth preserving, and "explicit user instruction" is a supervening authority that +overrides the default rule entirely. Reaching zero open PRs through any of this section's four +legitimate close paths is therefore consistent with §1's intent; what §1 actually forbids is reaching +zero via a Close that discards a still-valid, unmerged delta without first ensuring a successor +inherits it. ## 3. Research, standards, and documentation traceability -> 연구·표준·문서 추적성 모든 개발은 최신 권위 국제 표준·논문을 조사해 APA 7th로 인용하고 doctoring에 기록하며 누락 근거를 보충한다. Local Zotero API가 되면 기존 자료를 읽거나 OA 논문을 추가한다. 논문·표준은 exact-head·전체 PR·내부 모듈·API에 모순 없이 결합하고 충돌을 수정한다. AGENTS.md, CLAUDE.md, ARCHITECTURE.md, CHANGELOG.md 등 ADR 문서를 상시 갱신하고 Core ERD, UML, PRD, TRD, user stories, storyboard, wireframes, Storybook inventory, security·test·operability baseline 및 필요한 그림을 포함한다. 릴리즈 가능하면 버전을 올려 배포하고 CHANGELOG.md를 갱신한다. GitHub.io를 언급하려면 페이지를 실제 출판한다. +> 연구·표준·문서 추적성 모든 개발은 최신 권위 국제 표준·논문을 조사해 APA 7th로 인용하고 doctoring에 기록하며 누락 근거를 보충한다. Local Zotero API가 되면 기존 자료를 읽거나 OA 논문을 추가한다. 논문·표준은 exact-head·전체 PR·내부 모듈·API에 모순 없이 결합하고 충돌을 수정한다. AGENTS.md, CLAUDE.md, ARCHITECTURE.md, CHANGELOG.md 등 ADR 문서를 상시 갱신하고 Core ERD, UML, PRD, TRD, user stories, storyboard, wireframes, Storybook inventory, security·test·operability baseline 및 필요한 그림을 포함한다. 릴리즈 가능하면 버전을 올려 배포하고 CHANGELOG.md를 갱신한다. GitHub.io를 언급하려면 페이지를 실제 출판한다. 모든 의사결정은 작성자 자신이 맥락을 잊었거나 처음 보는 사람이 읽더라도 문제, 제약, 검토한 대안, 선택·기각 이유, 근거, 위험, 기대 효과와 후속 조치를 재구성할 수 있게 구체적이고 자세히 기록한다. 결론만 적거나 암묵적 전제를 생략하지 말고, 실제 사용자·운영·장애 장면이 떠오를 만큼 생생한 사례와 증거를 남긴다. 기록은 exact-head, 로그, 이슈·PR·ADR·실험 결과에 연결해 다른 Agent가 같은 판단을 검증·수정·계속할 수 있어야 한다. ## 4. UX/UI and customer-facing expression -> UX·UI와 고객 표현 필요하면 Figma와 Storybook(https://github.com/storybookjs/storybook), https://github.com/nextlevelbuilder/ui-ux-pro-max-skill, https://github.com/local-over/Anti-Slop-UI 를 함께 쓴다. 반복 웹 객체는 디자인 토큰화·모듈화하고 Figma File ID를 ADR에 기록한다. Storybook 장면별·Edge case별 Event를 조사·구현한다. UX·UI는 반드시 스크린샷으로 검수하고 ui-ux-pro-max로 Accessibility, Touch & Interaction, Performance, Style Selection, Layout & Responsive, Typography & Color, Animation, Forms & Feedback, Navigation Patterns, Charts & Data를 정의·검토·반영·적용·감사한다. 내부 구현 경계를 고객 화면에 노출하지 않고 문구로 고객의 다음 행동을 돕는다. Frontend는 디자인 토큰 CSS, 버튼 Action Edge, Interaction UX, i18n 번역 일관성까지 테스트한다. +> UX·UI와 고객 표현 필요하면 Figma와 Storybook(https://github.com/storybookjs/storybook), https://github.com/nextlevelbuilder/ui-ux-pro-max-skill, https://github.com/local-over/Anti-Slop-UI 를 함께 쓴다. UI는 모두 재사용 객체이고 페이지는 조합으로 만든다. 반복 웹 객체는 디자인 토큰화·모듈화하고 Figma File ID를 ADR에 기록한다. Storybook에서 정상·로딩·빈·오류·권한·반응형·상호작용 상태를 격리 개발·문서화하고 스크린샷·E2E로 접근성·터치·성능·타이포그래피·색상·폼·탐색·차트를 감사한다. ui-ux-pro-max로 Accessibility, Touch & Interaction, Performance, Style Selection, Layout & Responsive, Typography & Color, Animation, Forms & Feedback, Navigation Patterns, Charts & Data를 정의·검토·반영·적용·감사한다. shadcn/ui는 component source로 Storybook과 대체 관계가 아니다. Frontend stack은 고정하지 않으며 React·Vite·shadcn/ui·jQuery 4 등은 보안·유지보수·표준·접근성·성능을 충족할 때 쓴다. 내부 경계를 숨기고 다음 행동을 안내한다. Keyverse는 인증 backend로 유지하되(Direct Grant/ROPC 또는 Keycloak REST API), 로그인·가입·복구는 제품 자체 form으로 만든다. token CSS·Action Edge·Interaction UX를 검증한다. i18n은 한국어·영어·일본어·중국어·베트남어·스페인어·독일어·프랑스어를 지원한다. UI 폭·줄바꿈·CJK·텍스트 팽창·font fallback·locale 형식을 고려하고 언어별 Storybook·E2E로 잘림·겹침·의미 축약을 막는다. 번역 원장은 파일·JS bundle이 아닌 DB의 versioned resource다. server/native가 화면 key만 조회·cache하며 browser에 전체 catalog·무거운 i18n JavaScript를 싣지 않고 SPA를 전제하지 않는다. 공통 관리 제품이 없으면 새 저장소를 만들어 제품별 번역·검토·승인·배포·rollback API·관리 UI를 제공한다. + +**Context (2026-09-02):** the 2026-09-01 text already required i18n translation-consistency testing +in general terms; this revision makes the architecture itself an explicit, checkable requirement — +not "translate the strings" but "the translation ledger is a versioned DB resource that server/native +code queries per-screen-key with caching, never a static file or JS bundle the browser loads whole, +and never assumed to run inside an SPA." This is a genuinely new, currently-unimplemented product gap +for any ContextualWisdomLab product with a customer-facing UI (tracked in +`docs/product-technical-gap-baseline.md`, not yet audited against naruon's or any other product's +current i18n implementation as of this revision — that audit is deliberately left as a future Gap +increment, not done in this reconciliation pass). The eight named languages (ko/en/ja/zh/vi/es/de/fr) +and the "no shared management product yet ⇒ stand up a dedicated repo" clause are both new, +concrete, and testable — a Storybook/E2E suite per language that specifically checks for +truncation/overlap/meaning-loss under CJK width and text-expansion is the acceptance evidence this +directive now asks for, not a single default-locale screenshot pass. ## 5. Architecture, naming, and database conventions -> 아키텍처·명명·데이터베이스 소프트웨어는 중앙 .github, naruon, 다른 저장소와 연결 가능하게 만든다. DDD를 적용해 핵심·지원·일반 Subdomain, Bounded Context, Context Map, Ubiquitous Language를 ADR에 정의하고 Aggregate·Entity·Value Object·Domain Service·Repository·Domain Event·Invariant를 코드·API·DB·테스트에 일치시킨다. Aggregate는 최소 트랜잭션 경계로 두며 외부·레거시는 Anti-Corruption Layer로 격리하고 Shared Kernel은 최소화한다. 단독·반입 모듈 모두 우수한 모듈러 MSA를 지향하고 단일 소프트웨어가 Monolithic Architecture처럼 비대해지면 책임 경계에 따라 저장소를 분리한다. 소프트웨어명과 내부 호출자·클래스명이 다르거나 옛 이름(예: wardnet)을 쓰면 정식 이름으로 바꾼다. DB 객체명은 두 단어 이상의 snake case, Carmel case 또는 pascal case여야 하고 snake case를 우선한다. 위반명은 전부 치환한다. DB는 제3정규화와 Hot Partition 대비를 준수한다. Lock을 관리하고 불가하면 Read/Write DB를 분리한다. 영속화 경로의 항목별 UPSERT를 추적하고 없으면 계약을 보강한다. 명시적 구매자가 없는 제품은 코드 안팎의 Buyer를 정상 객체명으로 바꾼다. CSAP·SOC 2 인증을 고려한다. PII Masking이 업무를 마비시키므로 규정 준수형 비Masking 보호 대안을 설계한다. 실데이터 테스트·개발의 인명·기관명은 코드·ADR에서 익명화한다. GitHub Secrets의 PYPI API Key와 대부분 Public 배포라는 전제를 반영한다. +> 아키텍처·명명·데이터베이스 소프트웨어는 중앙 .github, naruon, 다른 저장소와 연결 가능하게 만든다. DDD를 적용해 핵심·지원·일반 Subdomain, Bounded Context, Context Map, Ubiquitous Language를 ADR에 정의하고 Aggregate·Entity·Value Object·Domain Service·Repository·Domain Event·Invariant를 코드·API·DB·테스트에 일치시킨다. Aggregate는 최소 트랜잭션 경계로 두며 외부·레거시는 Anti-Corruption Layer로 격리하고 Shared Kernel은 최소화한다. 단독·반입 모듈 모두 우수한 모듈러 MSA를 지향하고 단일 소프트웨어가 Monolithic Architecture처럼 비대해지면 책임 경계에 따라 저장소를 분리한다. 소프트웨어명과 내부 호출자·클래스명이 다르거나 옛 이름(예: wardnet)을 쓰면 정식 이름으로 바꾼다. DB 객체명은 두 단어 이상의 snake case, Carmel case 또는 pascal case여야 하고 snake case를 우선한다. 위반명은 전부 치환한다. DB는 제3정규화와 Hot Partition 대비를 준수한다. Lock을 관리하고 불가하면 Read/Write DB를 분리한다. 영속화 경로의 항목별 UPSERT를 추적하고 없으면 계약을 보강한다. 명시적 구매자가 없는 제품은 코드 안팎의 Buyer를 정상 객체명으로 바꾼다. CSAP·SOC 2 인증을 고려한다. PII Masking이 업무를 마비시키므로 규정 준수형 비Masking 보호 대안을 설계한다. 실데이터 테스트·개발의 인명·기관명은 코드·ADR에서 익명화한다. GitHub Secrets의 PYPI API Key와 대부분 Public 배포라는 전제를 반영한다. 변수·상수·인자·필드·함수·메서드·클래스·타입·모듈·패키지·API·DB 객체·파일·디렉터리는 두 단어 이상 snake_case·camelCase·PascalCase로 명명하고 snake_case를 우선한다. 언어·framework·외부 계약 관례는 경계에서 변환하며 위반명은 치환한다. **Reconciliation (flagged by Devin Review on this PR, 2026-08-30 — see `docs/doctoring/product-goal-directive.md`):** taken verbatim and cross-referenced against the rest of the ecosystem's own naming history, this section's quoted text reads backwards in two places: @@ -52,43 +207,307 @@ elsewhere; link to this file instead. Per this file's own conflict policy above: this note is the resolution, and `docs/CWL-MASTER-CONTEXT.md` §7 is the document that was right — do not force-rename wardnet or existing Camel/Pascal DB objects on the strength of this section's verbatim wording alone. +**Addition (2026-09-02, second revision):** this revision widens the two-or-more-word naming rule from +DB objects specifically to essentially every named code entity (variables, constants, arguments, +fields, functions, methods, classes, types, modules, packages, APIs, DB objects, files, directories), +still snake_case-preferred among snake_case/camelCase/PascalCase, and adds an explicit boundary- +conversion rule: a language/framework/external-contract's own naming convention gets converted *at the +boundary* (an adapter/ACL layer) rather than propagated inward — the same Anti-Corruption-Layer +principle this section already states for legacy/external systems generally, applied specifically to +naming. The grandfather clause above is not reopened by this widening: it was scoped to "existing +CamelCase/PascalCase **DB objects** specifically, per `CWL-MASTER-CONTEXT.md` §7," and that scope, +along with the wardnet correction, stands unchanged — the broader rule governs *new* identifiers of +every kind going forward, not a retroactive rename sweep across the whole codebase. + +**Addition (2026-09-02):** + +> 통합 온톨로지는 ConceptWeave가 observe→discover→propose→align→validate→review→publish와 semantic release를, semantic-data-portal이 catalog·governance·소비를, context-graph-contracts가 상호운용 계약을, enterprise-architecture-core가 Context Map·결정을 맡는다. domain truth·Ubiquitous Language는 제품 owner에 남긴다. 개념·관계·dimension·measure·mapping은 evidence·provenance·validity·confidence·status·deprecation·locale label을 가진 immutable release로 배포한다. consumer는 released API/contract·ACL만 쓰고 파일 복사·cross-service SQL·미승인 publication을 금지한다. UI 번역과 ontology label의 원장은 분리한다. + +This is a genuinely new, concrete repo-responsibility split for the org's ontology pipeline, not +previously recorded in this file. It is consistent with (not contradicted by) `semantic-data-portal`'s +existing description in `docs/CWL-MASTER-CONTEXT.md` (§35 there: "the higher ontology/catalog/ +governance plane ABOVE the doc KG... naruon owns the doc KG... SDP is not that store") — this +addition names the upstream half of that pipeline (ConceptWeave's +observe→discover→propose→align→validate→review→publish stages feeding SDP's catalog) and the two +cross-cutting-decision repos (`context-graph-contracts` for interop contracts, +`enterprise-architecture-core` for the Context Map itself) that `CWL-MASTER-CONTEXT.md` does not yet +name explicitly as of this revision — see §9's reconciliation note below for the same gap across +several repo names at once, and `docs/product-technical-gap-baseline.md` for the tracked follow-up to +add them there. The "UI translation ledger and ontology label ledger must never share a store" clause +directly cross-references §4's new i18n-DB-resource mandate above: they are two distinct versioned +resources with different owners (a product's own i18n management repo vs. ConceptWeave/SDP), not one +combined "everything is a translatable string" table. + ## 6. Implementation language, computation, and measurement principles -> 구현 언어·연산·측정 원칙 Docstring Coverage, Test Coverage, Edge Case Test Coverage를 각각 100%로 만든다. 초보자가 별도 코드 분석 없이 이해할 수 있을 만큼 충분한 docstring을 제공한다. 수리과학, Psychometrics, Exploratory Data Analysis, 데이터과학의 모든 core 연산 레이어는 Python으로 구현하지 말고 무조건 Rust로 작성한다. Vector 연산, Linear Algebra, Matrix Algebra, LLM token size 연산도 포함한다. GPU와 CPU multithreaded 실행을 지원하고 context switching을 최소화한다. 속도·안정성·보안이 중요한 일반 소프트웨어도 Rust를 사용하며, 기존 타 언어 구현은 전환·리팩터링하거나 명확한 Rust API Call 경계로 분리한다. 확률표집 계약에는 표본 설계, 오차 목표, 실패 분모를 명시해 ADR과 감사 코드에 반영한다. Atomistic fallacy를 막도록 다층구조·다중소속 모델링을 고려·구현하고 시간 흐름을 반영하는 모델도 포함한다. 가중치는 임의로 정하지 말고 수리과학·Psychometrics에서 추정된 값, 특히 fast-mlsirm이나 TEPP처럼 논문 근거가 있는 모형을 사용한다. 어떠한 휴리스틱과 Rule of thumbs도 금지하며, 근거 미확정 상태로 방치하지 말고 ContextualWisdomLab의 추론 엔진을 최대한 활용하고 SOLID 원칙을 지킨다. Deprecation Warning은 Suppression하지 말고 근본 문제를 해결한다. 합성 데모 데이터는 Unit test에는 쓸 수 있으나 Production에 반영하지 않는다. Python 웹 서버는 Multithreading을 지원하고 GIL이 문제면 Python 3.14를 사용한다. +> 구현 언어·연산·측정 원칙 Docstring Coverage, Test Coverage, Edge Case Test Coverage를 각각 100%로 만든다. 초보자가 별도 코드 분석 없이 이해할 수 있을 만큼 충분한 docstring을 제공한다. 수리과학, Psychometrics, Exploratory Data Analysis, 데이터과학의 모든 core 연산 레이어는 Python으로 구현하지 말고 무조건 Rust로 작성한다. Vector 연산, Linear Algebra, Matrix Algebra, LLM token size 연산도 포함한다. GPU와 CPU multithreaded 실행을 지원하고 context switching을 최소화한다. 속도·안정성·보안이 중요한 일반 소프트웨어도 Rust를 사용하며, 기존 타 언어 구현은 전환·리팩터링하거나 명확한 Rust API Call 경계로 분리한다. 확률표집 계약에는 표본 설계, 오차 목표, 실패 분모를 명시해 ADR과 감사 코드에 반영한다. Atomistic fallacy를 막도록 다층구조·다중소속 모델링을 고려·구현하고 시간 흐름을 반영하는 모델도 포함한다. 가중치는 임의로 정하지 말고 수리과학·Psychometrics에서 추정된 값, 특히 fast-mlsirm이나 TEPP처럼 논문 근거가 있는 모형을 사용한다. 어떠한 휴리스틱과 Rule of thumbs도 금지하며, 근거 미확정 상태로 방치하지 말고 ContextualWisdomLab의 추론 엔진을 최대한 활용하고 SOLID 원칙을 지킨다. Deprecation Warning은 Suppression하지 말고 근본 문제를 해결한다. 합성 데모 데이터는 Unit test에는 쓸 수 있으나 Production에 반영하지 않는다. Python 웹 서버는 Multithreading을 지원하고 GIL이 문제면 Python 3.14를 사용한다. Python은 비선호며 LLM 편의로 고르지 않는다. Python 전용 ML runtime에 실용적 Rust 대안이 없을 때만 그 부분에 쓰며 범위·근거·제거 조건을 ADR에 남기고 hot path는 Rust로 둔다. Python web server는 multithread이며 GIL 병목은 3.14나 Rust로 푼다. + +**Addition (2026-09-02, second revision):** sharpens the existing "core computation layers in Rust, +not Python" mandate into an explicit narrow-exception rule: Python is disfavored outright and must +never be chosen merely for LLM/agent-tooling convenience; the one permitted exception is a +Python-only ML runtime with no practical Rust alternative, and even then only for that specific part — +scope, rationale, and removal condition go in an ADR, and the hot path itself still has to be Rust. It +also names Rust as an explicit alternative to upgrading to Python 3.14 for a GIL bottleneck, alongside +the version bump already in this section. Neither changes this section's existing Rust-first mandate; +both make an already-strict rule stricter and more auditable (an ADR trail for the one allowed +exception) rather than looser. ## 7. Realistic verification, load, and container testing -> 현실성 있는 검증과 부하·컨테이너 테스트는 제품 특성에 맞는 현실 사례와 정확성 기준을 포함한다. Psychometrics는 true parameter 대비 estimation RMSE와 true parameter 추정 재현성을 검증하고, 음악 분석은 실제 음원이 기대 분석값을 내는지 확인한다. 웹을 지원하면 Asynchronous 처리를 구현해 무응답을 방지하고 k6 end-to-end load test로 동시 접속 능력과 병목을 측정·개선한다. close_connection을 인스턴스 속성으로만 가정하는 잠재 버그를 점검한다. Docker는 Podman 또는 colima로 대체할 수 있다. 컨테이너 병목이면 shm_size와 PostgreSQL 등 응용 설정을 하드웨어에 맞게 자동 튜닝한다. 주로 compose로 운영해 k8s 전환성을 확보한다. Docker container 프로젝트명은 고정하되 테스트 격리 때만 override하고 달성 후 격리 컨테이너를 제거한다. MLX·CPU·CUDA·OpenCL의 Docker/Podman/Colima 처리법을 ADR에 기록·반영하고 Native Module 분리가 필요하면 독립 서비스로 개발한다. +> 현실성 있는 검증과 부하·컨테이너 테스트는 제품 특성에 맞는 현실 사례와 정확성 기준을 포함한다. Psychometrics는 true parameter 대비 estimation RMSE와 true parameter 추정 재현성을 검증하고, 음악 분석은 실제 음원이 기대 분석값을 내는지 확인한다. 웹을 지원하면 Asynchronous 처리를 구현해 무응답을 방지하고 k6 end-to-end load test로 동시 접속 능력과 병목을 측정·개선한다. E2E 테스트의 합격 조건은 페이지당 처리시간 p95 20ms 이하이며, 초과 시 병목을 제거하고 재검증한다. 모든 페이지가 통과해야 한다. 초과하면 알고리즘·query·I/O·rendering을 profile하고 runtime·언어·framework가 원인이면 계약·정확성을 보존해 Rust 우선 기술·hot path·개발 언어를 바꾼다. 표본 축소·측정 제외·비현실적 cache warm-up을 금지한다. JavaScript bundle·heap·DOM·hydration·main thread·GC가 메모리·지연을 키우면 dependency·Frontend stack을 교체한다. close_connection을 인스턴스 속성으로만 가정하는 잠재 버그를 점검한다. JavaScript bundle·heap·DOM·hydration·main thread·GC가 메모리·지연을 키우면 dependency·rendering·Frontend stack을 교체한다. close_connection도 점검한다. Docker는 Podman 또는 colima로 대체할 수 있다. 컨테이너 병목이면 shm_size와 PostgreSQL 등 응용 설정을 하드웨어에 맞게 자동 튜닝한다. 주로 compose로 운영해 k8s 전환성을 확보한다. Docker container 프로젝트명은 고정하되 테스트 격리 때만 override하고 달성 후 격리 컨테이너를 제거한다. MLX·CPU·CUDA·OpenCL의 Docker/Podman/Colima 처리법을 ADR에 기록·반영하고 Native Module 분리가 필요하면 독립 서비스로 개발한다. + +**Addition (2026-09-02):** two anti-gaming clauses for the p95≤20ms criterion the 2026-09-01 revision +added, not previously spelled out: (1) never satisfy the target by shrinking the sample, excluding +measurements, or an unrealistic cache warm-up before measuring — the bar is real traffic patterns, +not a benchmark rigged to pass; (2) when the JS bundle/heap/DOM/hydration/main-thread/GC is the actual +memory or latency driver, the fix is to replace the dependency or the frontend stack itself, not to +accept the slower ceiling. Both reinforce, rather than change, the profile-first-then-fix-the-real- +cause approach already in this section (algorithm/query/I/O/rendering profiling before reaching for a +Rust rewrite) — the new text just forecloses the two most tempting ways to "pass" the check without +actually fixing anything. (Devin Review, 2026-09-02: the container-requirements sentences — Docker/ +Podman/Colima substitution, `shm_size`/PostgreSQL auto-tuning, compose-first operation for k8s +portability, fixed-then-overridable container project naming, and the MLX/CPU/CUDA/OpenCL ADR +requirement — were originally appended after this English commentary instead of inside the `>` +blockquote above, so a consumer extracting only the ten quoted sections would have silently missed +binding directive text. Moved into the blockquote itself, verbatim and unparaphrased; this commentary +paragraph now contains only the anti-gaming-clause explanation it was written for.) ## 8. LLM, orchestration, and embedding -> LLM·오케스트레이션·Embedding LLM이 필요한 테스트는 contextual-orchestrator 기반 OpenCode Agent로 만든다. contextual-orchestrator는 GitHub Secrets의 BYTEZ_API_KEY, NVIDIA_NIM_API_KEY, NVIDIA_NIM_API_KEY_SUB, OPENROUTER_API_KEY, OPENAI_API_KEY를 모두 써 auto model discovery로 최적 모형을 제공한다. embedding·responses·completions, audio, video, image, ommi-modal 등 가용 모델을 폭넓게 지원한다. 가능하면 반입해 쓰고 발견한 해당 저장소 문제도 함께 수정한다. LLM 사용 소프트웨어와 contextual-orchestrator는 Fugu·Conductor·TRINITY 연구를 근거로 단일 모델 라우팅과 심층 다중 Agent 오케스트레이션 사이의 계산량을 배분한다. 워크플로 단계, 재귀 깊이, 작업 분해, 접근 목록으로 test-time compute를 조절하고 역할별 reasoning effort를 다르게 하며 추론 수준 ablation을 수행한다. 속도는 핵심 고려사항이 아니며 정확성을 우선한다. 중앙 OpenCode, Strix, Noema는 모델당 두 시간 이상 걸릴 수 있음을 수용한다. LLM Chat model은 chat completion API와 responses API를 모두 지원하고 json_object와 json_schema를 모두 처리한다. Embedding은 문단·구문·DOM·송수신자 등 의미 단위를 식별해 chunking한다. 본문에 base64 이미지가 있으면 텍스트 인식, 객체 인식, 태그 설명, 이미지 별도 검색 방법을 연구 근거와 함께 DB 설계에 넣고 원래 삽입 위치를 보존해 그림 맥락까지 검색·표현한다. GitHub Actions scheduler는 contextual-orchestrator 기반 OpenCode Agent로 전환한다. COPILOT_GITHUB_TOKEN은 쓰지 않고 기존 리뷰 Agent 키 체계를 유지한다. +> LLM·오케스트레이션·Embedding LLM이 필요한 테스트는 contextual-orchestrator 기반 OpenCode Agent로 만든다. contextual-orchestrator는 GitHub Secrets의 BYTEZ_API_KEY, NVIDIA_NIM_API_KEY, NVIDIA_NIM_API_KEY_SUB, OPENROUTER_API_KEY, OPENAI_API_KEY를 모두 써 auto model discovery로 최적 모형을 제공한다. embedding·responses·completions, audio, video, image, ommi-modal 등 가용 모델을 폭넓게 지원한다. 가능하면 반입해 쓰고 발견한 해당 저장소 문제도 함께 수정한다. released API·client·schema로 연결한다. 통합 CI는 .github reusable workflow와 thin caller로 구성한다. owner PR·release·consumer 변경마다 exact SHA로 build·API/schema contract·E2E·model behavior·security·SBOM·provenance를 검증한다. 결함은 owner에서 RED→fix→GREEN→release하고 consumer version을 올린다. mutable head·branch URL·cross-repo source·workflow 복제를 금지하며 bridge에는 owner issue·만료·삭제 조건을 둔다. LLM Provider group 이름을 코드·설정·테스트·라우팅 조건에 하드코딩하지 않는다. 그룹명은 관리·표시용 별칭으로만 취급하고, modality, context window, reasoning capability·effort, tool calling, structured output, streaming, 가격·지연·가용성·정확도 등 자동 발견·검증된 모델 특성에 따라 선택·fallback·개발 적용을 결정한다. 공급자나 그룹명이 바뀌어도 기능 분기가 깨지지 않게 한다. LLM Model에는 애플리케이션·Agent·Gateway 공통의 획일적 timeout 상한을 두지 않는다. 통신 장애는 upstream LLM provider가 자체 timeout과 오류로 종료하므로 기본값은 무제한(null)로 둔다. 관리자 Web에서 모델별 timeout을 조회·설정·해제·복원할 수 있게 하고 단위, 우선순위, 상속, 입력 검증, 감사 이력과 API 계약을 구현한다. 관리자 설정이 있을 때만 해당 값으로 제한하며 reasoning·streaming·tool call이 진행 중인 요청을 단순 경과시간으로 취소하지 않는다. 사용자 취소, provider 종료, 관리자 timeout을 구분해 기록한다. LLM 사용 소프트웨어와 contextual-orchestrator는 Fugu·Conductor·TRINITY 연구를 근거로 단일 모델 라우팅과 심층 다중 Agent 오케스트레이션 사이의 계산량을 배분한다. 워크플로 단계, 재귀 깊이, 작업 분해, 접근 목록으로 test-time compute를 조절하고 역할별 reasoning effort를 다르게 하며 추론 수준 ablation을 수행한다. 속도는 핵심 고려사항이 아니며 정확성을 우선한다. 중앙 OpenCode, Strix, Noema는 모델당 두 시간 이상 걸릴 수 있음을 수용한다. LLM Chat model은 chat completion API와 responses API를 모두 지원하고 json_object와 json_schema를 모두 처리한다. Embedding은 문단·구문·DOM·송수신자 등 의미 단위를 식별해 chunking한다. 본문에 base64 이미지가 있으면 텍스트 인식, 객체 인식, 태그 설명, 이미지 별도 검색 방법을 연구 근거와 함께 DB 설계에 넣고 원래 삽입 위치를 보존해 그림 맥락까지 검색·표현한다. GitHub Actions scheduler는 contextual-orchestrator 기반 OpenCode Agent로 전환한다. COPILOT_GITHUB_TOKEN은 쓰지 않고 기존 리뷰 Agent 키 체계를 유지한다. + +**Addition (2026-09-02, second revision):** two genuinely new sentences not previously in this section. +First, "released API·client·schema로 연결한다" — consumers connect to a *released* contract, not a +mutable branch — which is the same "immature core" principle §2 states as a development-process rule +and §9 states as a repository-selection rule, now stated a third time as the specific consumption +contract for `contextual-orchestrator` integration itself; it does not contradict the adjacent +"가능하면 반입해 쓰고... 수정한다" sentence, which is about `contextual-orchestrator` importing and +fixing *its own* upstream dependencies (provider SDKs, client libraries), a different relationship +than how *this ecosystem's other repos* consume `contextual-orchestrator`. Second, a detailed CI +integration architecture: unified CI as `.github` reusable workflows plus thin callers (matching the +`CLAUDE.md`-documented "product hourly callers stay thin" convention, now elevated into the directive +itself); on every owner PR/release/consumer change, verify build/API-schema-contract/E2E/model- +behavior/security/SBOM/provenance at an exact SHA; defects get fixed at the owner via RED→fix→GREEN→ +release with a consumer version bump, never patched around in the consumer; mutable-head references, +branch URLs, cross-repo source copies, and workflow duplication are all forbidden; and any transitional +bridge mechanism needs an owner-tracked issue plus an explicit expiration/deletion condition (directly +echoing this repo's own `pr-review-autofix.yml` vendoring pattern and its `docs/CWL-MASTER-CONTEXT.md` +§7 "no drift-source repository-local copies" convention). Not yet audited against every current CI +integration in this session's four in-scope repos for full compliance — recorded as the standard, not +asserted as already-verified everywhere. **Note (flagged by CodeRabbit on this PR, 2026-08-30):** section 8's quoted text describes `contextual-orchestrator`'s general product capability — broad model/modality support and all-five-secret auto model discovery as a *design principle for the orchestrator itself*. It does not specify, and must not be read as overriding, which pool each CI consumer routes through: that is governed exclusively by `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md` and its doctoring records — `OpenCode` and `Noema` use the fail-closed, ZDR-prioritized `orchestrator/free` pool; only `Strix` security analysis uses the provider-diverse `orchestrator/auto` pool; private/internal review targets require an attested ZDR-only catalog and never fall back to a non-ZDR provider. Do not loosen any CI consumer's pool or credential scope on the strength of this section's general wording alone. **Note (2026-08-30, superseded by the merged pin flip — see the correction below):** an earlier draft of this note said Strix stayed on `orchestrator/auto` pending `free_family_diversity` reaching `>= 2`. That is no longer true and must not be read as current: `.github/workflows/strix.yml` now hardcodes `STRIX_MODEL`/`CONTEXTUAL_ORCHESTRATOR_POOL` to `orchestrator/free` and fails closed on any other value. This note originally went on to say that ADR-0003's 2026-08-30 amendment "records the owner's decision to accept the residual single-outage-domain risk immediately rather than wait for the evidence-gated threshold this note originally described" — that framing was false, as ADR-0003's own 2026-08-31 correction now records: no owner reviewed or accepted this switch or its risk. `free_account_diversity` (`scripts/ci/contextual_orchestrator_review_policy.py`; renamed from `free_family_diversity` once every KV credential became an independent discovery account rather than being grouped into a vendor "family", see #1468) remains useful as ongoing monitoring evidence for that open, unreviewed risk, not as a gate blocking the pin. +**Note (2026-09-02, Devin Review reconciliation):** §8's "LLM Provider group 이름을 코드·설정·테스트· +라우팅 조건에 하드코딩하지 않는다" and §10's "GitHub Actions Workflow 이용에 관해 orchestrator/free 로 +고정" read as a direct contradiction taken in isolation — Devin Review flagged exactly this ("agents +cannot satisfy both"). They govern different things and are not actually in tension: §8's prohibition +is about **behavioral feature branching** — application/Agent/gateway code must never select a model, +change capability handling, or gate a code path on a string match against a provider *group* name +(e.g. `if group == "openai": ...`), because group membership is a display alias that can be +re-partitioned without notice, while the underlying auto-discovered model characteristics (modality, +context window, reasoning effort, tool calling, structured output, streaming, price/latency/ +availability/accuracy) are what must drive behavior. §10's pin is a **CI admission-pool selection**, +not behavior branching: `CONTEXTUAL_ORCHESTRATOR_POOL=free` in a required-check workflow tells the +sidecar which cost/ZDR-governed *admission pool* a security-critical CI job may draw candidates from +at all — it changes no application code path, no feature, and no model-capability handling; every +model actually selected from within that pool is still chosen by the same auto-discovery/capability +ranking §8 requires. Reading §8 narrowly as "no group-name string literal may appear anywhere, +including infrastructure/CI configuration" would make §10 itself impossible to state, which cannot +have been the intent of a revision that added both in the same document. No text is weakened by this +reconciliation — §8's quote is unchanged, and CI's `orchestrator/free` pin (§10, `strix.yml`) remains +exactly as narrow and audited as before (see `docs/product-technical-gap-baseline.md`'s "`auto` +removed as an accepted value" entry for the fail-closed enforcement of that narrowness). This +revision's re-issued §8 text again says "`orchestrator/free` 고정" ("pinned +to orchestrator/free"), but states it as a bare clause inside §8's general body rather than as a +separately scope-qualified item. Read together with §10 below (added 2026-09-01, wording refined the +same day to add "GitHub Actions Workflow 이용에 관해" — i.e. this governs CI-consumer workflows, not +`contextual-orchestrator`'s general product capability for other callers) and with this section's own +first (CodeRabbit) note above, that scope qualifier is not being reopened or loosened by this +restatement: it was independently verified against `strix.yml`'s actual `case` statements, not merely +asserted, and a shorter restatement omitting a qualifier already established elsewhere in the same +document is a compression artifact, not a reversal. §10 remains the authoritative "what is currently +pinned, for which consumers" record. + ## 9. Reference libraries, tool invocations, and ecosystem repositories > 참고 라이브러리와 호출 @Superpowers @GitHub @Figma @Visualize @Context7 @Product Design @Consensus를 활용한다. -- **TEPP** — https://github.com/ContextualWisdomLab/TEPP — 다국어·시간·관계 측정용 Temporal Event Psychometrics Platform이며 통계·심리측정 산술은 Rust로 구현한다. -- **contextual-orchestrator** — https://github.com/ContextualWisdomLab/contextual-orchestrator — 논문 근거의 contextual model orchestration lab·enterprise admin design. -- **fast-mlsirm** — https://github.com/ContextualWisdomLab/fast-mlsirm — simple-structure MLSIRM/MLS2PLM은 Jeon, Jin, Schweinberger, and Baugh(2021), Kang and Jeon(2025), Molenaar and Jeon(2026)을 따른다. 인접 화면: Angoff delta-plot DIF(docs/delta_plot_dif.md), Bradley–Terry MM ranking(docs/bradley_terry_mm.md). 주요 인용·결정: docs/traceability/research-basis.md, docs/adr/README.md. 점수 해석·공정성은 AERA·APA·NCME(2014)를 따르며 이는 CWE/OWASP/NIST 통제가 아니다. -- **keyverse** — https://github.com/ContextualWisdomLab/keyverse — Keycloak 기반 독립 컴포넌트(Apache-2.0)이자 ContextualWisdom ecosystem 중앙 Identity Provider. -- **RankWeave** — https://github.com/ContextualWisdomLab/RankWeave — Python 3.10+용 무의존성·저장소 비종속 retrieval fusion/evaluation/statistical comparison/tuning/TREC benchmarking/auditable CLI workflow. -- **ThreadWeave** — https://github.com/ContextualWisdomLab/ThreadWeave — runtime dependency 없는 Python용 표준 기반 JWZ/RFC 5256 이메일 reference threading. +> Core foundation은 전 제품의 공통 설치물이 아니다. 여러 제품에서 반복되는 책임을 한 저장소가 canonical owner로서 독립 배포·versioned contract를 제공하는 선택형 control plane·service·library다. 보호 브랜치의 문서·API/schema·release evidence로 역할·성숙도를 확인하며 open PR은 Proposed 상태다. + +- **.github** — https://github.com/ContextualWisdomLab/.github — workflow·review/security/release owner이며 ruleset·얇은 workflow_call로만 쓴다. +- **enterprise-architecture-core** — https://github.com/ContextualWisdomLab/enterprise-architecture-core — **context-graph-contracts** — https://github.com/ContextualWisdomLab/context-graph-contracts — 전사 결정·versioned context 계약 원장이며 runtime·제품 DB는 제외한다. +- **ConceptWeave** — https://github.com/ContextualWisdomLab/ConceptWeave — **semantic-data-portal** — https://github.com/ContextualWisdomLab/semantic-data-portal — ontology 생성·publish와 catalog·governance·소비를 분담한다. +- **contextual-orchestrator** — https://github.com/ContextualWisdomLab/contextual-orchestrator — 논문 근거의 contextual model orchestration lab·enterprise admin design. **noema** — https://github.com/ContextualWisdomLab/noema — 모델 orchestration과 GitHub OIDC 단기 권한·exact-head evidence를 contextual-orchestrator와 분담한다. +- **keyverse** — https://github.com/ContextualWisdomLab/keyverse — Keycloak 기반 독립 컴포넌트(Apache-2.0)이자 ContextualWisdom ecosystem 중앙 Identity Provider. 제품은 OIDC/OAuth·SCIM·자체 form을 쓰고 table은 복제하지 않는다. +- **EgressWeave** — https://github.com/ContextualWisdomLab/EgressWeave — **OriginWeave** — https://github.com/ContextualWisdomLab/OriginWeave — **pingora-gateway** — https://github.com/ContextualWisdomLab/pingora-gateway — **quarantine-sandbox-runtime** — https://github.com/ContextualWisdomLab/quarantine-sandbox-runtime — outbound·browser·edge·격리 core이며 부족한 기능은 owner에서 완성한다. +- **pg-llm-batch** — https://github.com/ContextualWisdomLab/pg-llm-batch — **EmbedRelay** — https://github.com/ContextualWisdomLab/EmbedRelay — batch/token과 embedding identity·vector migration owner다. +- **fast-mlsirm** — https://github.com/ContextualWisdomLab/fast-mlsirm — simple-structure MLSIRM/MLS2PLM은 Jeon, Jin, Schweinberger, and Baugh(2021), Kang and Jeon(2025), Molenaar and Jeon(2026)을 따른다. 인접 화면: Angoff delta-plot DIF(docs/delta_plot_dif.md), Bradley–Terry MM ranking(docs/bradley_terry_mm.md). 주요 인용·결정: docs/traceability/research-basis.md, docs/adr/README.md. 점수 해석·공정성은 AERA·APA·NCME(2014)를 따르며 이는 CWE/OWASP/NIST 통제가 아니다. **TEPP** — https://github.com/ContextualWisdomLab/TEPP — 다국어·시간·관계 측정용 Temporal Event Psychometrics Platform이며 통계·심리측정 산술은 Rust로 구현한다. 둘 다 IRT/MLSIRM과 다국어·시간·event·relation 측정 owner이며 kernel 재구현을 금지한다. +- **RankWeave** — https://github.com/ContextualWisdomLab/RankWeave — Python 3.10+용 무의존성·저장소 비종속 retrieval fusion/evaluation/statistical comparison/tuning/TREC benchmarking/auditable CLI workflow. **ThreadWeave** — https://github.com/ContextualWisdomLab/ThreadWeave — runtime dependency 없는 Python용 표준 기반 JWZ/RFC 5256 이메일 reference threading. 둘 다 retrieval fusion/evaluation/TREC와 JWZ/RFC 5256 threading owner다. +- **inkspan** — https://github.com/ContextualWisdomLab/inkspan — **DiagramWeave** — https://github.com/ContextualWisdomLab/DiagramWeave — editor/serialization과 diagram patch/render/CLI/LSP package다. +- **mhtml-etl-gateway** — https://github.com/ContextualWisdomLab/mhtml-etl-gateway — MHTML 검사·schema proposal·load·lineage owner다. +- **appguardrail** — https://github.com/ContextualWisdomLab/appguardrail — **wardnet** — https://github.com/ContextualWisdomLab/wardnet — ContextualWisdomLab Rust-first gateway·SOC control-plane baseline. 둘 다 SAST/SARIF와 Rust gateway/SOC baseline owner이며 범위를 과장하지 않는다. - **disksage** — https://github.com/ContextualWisdomLab/disksage — Windows/Linux/macOS 디스크 공간 관리자. 드라이브를 스캔하고 완전 오프라인 온디바이스 LLM이 삭제 안전성을 조언하며 OWL ontology로 파일을 정리한다. -- **wardnet** — https://github.com/ContextualWisdomLab/wardnet — ContextualWisdomLab Rust-first gateway·SOC control-plane baseline. - **LineageWeave** — https://github.com/ContextualWisdomLab/LineageWeave — 명시적 선후행 링크 없는 짧은 timestamped record에서 git-branch식 lineage DAG를 재구성해 평면 자료를 탐색 가능한 branching thread로 바꾼다. 수리 연산은 소관이 아니므로 다른 라이브러리로 이관한다. +> naruon·LineageWeave·psychometrics-commons·disksage·PolicyWeave·CalendarWeave·supply-chain-control-plane은 완성도가 아니라 domain product/composition consumer라 분류한다. 공통 기능은 core owner로 추출해 통합 CI로 개발한다. + +**Reconciliation (2026-09-02):** this revision roughly triples §9's repo catalog and gives most +entries an explicit responsibility statement for the first time in this file. Cross-checked against +`docs/CWL-MASTER-CONTEXT.md` where possible: `semantic-data-portal`, `pg-llm-batch`, `appguardrail`, +`inkspan`, `wardnet`, `keyverse`, `naruon`, `TEPP`, `fast-mlsirm`, `RankWeave`, `ThreadWeave`, +`disksage`, `LineageWeave`, `contextual-orchestrator`, and `noema` all already appear there and this +section's descriptions are consistent with (additive to, not contradicting) that file. This session +could **not** independently verify `ConceptWeave`, `context-graph-contracts`, +`enterprise-architecture-core`, `EgressWeave`, `OriginWeave`, `pingora-gateway`, +`quarantine-sandbox-runtime`, `EmbedRelay`, `DiagramWeave`, `mhtml-etl-gateway`, +`psychometrics-commons`, `PolicyWeave`, `CalendarWeave`, or `supply-chain-control-plane` against +`docs/CWL-MASTER-CONTEXT.md` (that file's own catalog does not yet name them as of this revision, and +this session's repository access does not extend to them) — recorded here verbatim per this file's +own policy (durable knowledge belongs in the repo, not private memory) rather than held back pending +verification, with a tracked follow-up in `docs/product-technical-gap-baseline.md` to add them to +`CWL-MASTER-CONTEXT.md`'s own ecosystem catalog once an agent with access to those repos (or the +owner) can confirm the responsibility split above against their actual current state. The "extract +shared functionality to a core owner" closing sentence directly reinforces §2's new "immature core" +protocol above — the same principle stated once as a development-process rule (§2) and once as a +repository-selection rule (§9). + +**Addition (2026-09-02, second revision):** three genuinely new pieces of content. First, the +"Core foundation은 전 제품의 공통 설치물이 아니다..." blockquote added above (right after the tool-list +quote) is a definitional framing not previously present anywhere in this file: a core-foundation repo +is a *selective*, independently-versioned control plane/service/library owned by one canonical repo +for a responsibility that repeats across products — never a default install every product must carry — +and its actual role/maturity is confirmed from the **protected branch's** docs/API-schema/release +evidence, not from an open PR's own claims (an open PR is "Proposed" status only, regardless of how +confidently its description is written). This directly matches this session's own established +practice throughout `.github#1659`'s reconciliation work (treating "Current exact authority" language +in a PR body as a claim to verify, not a fact) and gives it explicit standing-directive backing. +Second, the flat, un-categorized repo list above (already reconciled in the 2026-09-02 entry) is +regrouped by this revision into five named domains, worth recording as a distinct piece of information +even though the individual repo-to-responsibility mappings mostly match what is already listed above: + +> 조직·계약 — .github: 공통 CI·review·security·release; enterprise-architecture-core: 전사 Context Map·architecture decision; context-graph-contracts: assertion·event·schema·fixture·conformance. domain truth는 제품에 남긴다. +> 의미·데이터 — ConceptWeave: ontology·semantic-layer 생성·검증·release. semantic-data-portal: catalog·governance·검색·제공. EmbedRelay: embedding identity·migration. mhtml-etl-gateway: MHTML 검사·schema proposal·load lineage. +> AI·운영 — CO: provider discovery·model capability·routing/delegation/verification/admin. noema: GitHub Actions OIDC 단기 repository capability·exact-revision evidence. pg-llm-batch: DB token count·batch 처리. +> Identity·보안·runtime — keyverse: identity·federation·token. EgressWeave: 안전한 outbound HTTP. OriginWeave: governed browser. pingora-gateway: Rust edge. quarantine-sandbox-runtime: 격리. appguardrail: scan·SARIF·remediation. wardnet: gateway·WAF·IDS·SOC. +> 재사용 기능 — fast-mlsirm: IRT·MLSIRM. TEPP: 다국어·시간·event·relation 측정. RankWeave: retrieval fusion·evaluation·통계 비교·tuning·TREC. ThreadWeave: JWZ/RFC 5256 threading. inkspan: editor·serialization·문서 변환. DiagramWeave: diagram patch·render·CLI·LSP. + +Third, a concrete elaboration of the "immature core" protocol's *waiting-period* mechanics, not +previously spelled out in either §2 or §9's existing text: + +> owner가 미성숙하거나 API가 없어도 consumer가 복제·우회하지 않는다. owner에서 RED test→기능·문서·release를 개발해 CI GREEN과 immutable version을 낸 뒤 채택한다. 그 전에는 port·ACL·feature flag·test double로 경계를 지키고 owner의 source·DB·임시 branch를 직접 읽지 않는다. + +This names the specific techniques (a port, an ACL, a feature flag, a test double) a consumer must use +to hold its boundary *while waiting* for an immature owner to catch up, and adds an explicit +prohibition §2's original text did not state: never read the owner's raw source, database, or a +temporary/working branch directly, even as a stopgap. Together with §2's protocol and this section's +own closing sentence above, this is now the third and most operationally specific statement of the +same "immature core" principle in this file. + +## 10. Contextual-orchestrator pool pin + +> Contextual-Orchestrator의 모델은 GitHub Actions Workflow 이용에 관해 orchestrator/free 로 고정. + +> GitHub Actions의 model-backed workflow는 orchestrator/free로 고정한다. 무료 후보 discovery·routing·fallback은 CO 내부에서만 한다. workflow는 provider·model·group명·유료 fallback을 지정하지 않고 gateway token만 쓴다. capability가 없으면 유료 우회 없이 fail closed해 free pool·contract·CI를 보완한다. + +**Context (added 2026-09-01, wording refined the same day by a follow-up `/loop` invocation to add +the scope qualifier "GitHub Actions Workflow 이용에 관해" — i.e. this pin governs CI-consumer +workflows, not `contextual-orchestrator`'s general product capability for other callers):** this +item crystallizes, into the primary numbered directive itself, a decision that previously lived +only in an annotation below §8 (the "Note (2026-08-30, superseded...)" above). That note already +recorded that `.github/workflows/strix.yml` hardcodes `STRIX_MODEL`/`CONTEXTUAL_ORCHESTRATOR_POOL` +to `orchestrator/free` and fails closed on any other value — confirmed still true by direct +inspection of `strix.yml` at the time of this revision (the `case` statements gating +`STRIX_MODEL_REQUESTED`/`STRIX_MODEL` accept only `orchestrator/free`/ +`contextual-orchestrator/orchestrator/free` and `::error::` on anything else). This item makes that +pin an explicit standing instruction rather than something an agent could only discover by reading a +superseded-vs-superseding note pair below §8. It does not introduce a new technical requirement for +the workflows already pinned — `OpenCode`, `Noema`, and `Strix` (the three required-check GitHub +Actions Workflows) are now all pinned to the fail-closed, ZDR-prioritized `orchestrator/free` pool, +superseding the older "Strix uses the provider-diverse `orchestrator/auto` pool" framing in §8's +first (CodeRabbit) note above, which itself predates the correction in the second note. The added +qualifier does clarify scope, though: it binds *GitHub Actions Workflow* consumers specifically, not +every possible caller of `contextual-orchestrator` — consistent with §8's own general-capability +framing (broad model/modality support, auto-discovery across all five provider secrets) being a +product-level design principle for the orchestrator itself, not a CI routing policy for every +consumer. `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md` remains the authoritative +record for *why*; this item and the §8 notes together are the authoritative record for *what is +currently pinned, and for which consumers*. + +**Reconciliation (flagged by Devin Review on this PR, 2026-09-02):** `AGENTS.md` and ADR-0003's +2026-08-31 correction both still say the **original 2026-08-30 implementation** switch (the commit +that made `strix.yml` hardcode `orchestrator/free`) was made unilaterally by an autonomous agent +session, "not per any owner decision," and that the resulting single-outage-domain availability risk +"remains an open, unreviewed risk... reverting to `orchestrator/auto` pending a real decision is a +legitimate option, not foreclosed by anything in this record." Read next to this item — which presents +`orchestrator/free` pinning as something the owner directed — that can look like a flat contradiction: +was this owner-authorized or not? It is not a contradiction once two separate facts are kept distinct, +neither one superseding the other: + +1. **The 2026-08-30 implementation event** stays exactly as `AGENTS.md`/ADR-0003 describe it: an agent's + unilateral action, with a fabricated claim of owner direction that was retracted the next day. This + item does not revise that history. +2. **This item itself (§10) is a separate, later, genuine owner directive** — the owner issued it via + `/loop` on 2026-09-01, distinct from and subsequent to the 2026-08-30 event. That *is* real owner + authorization for the **policy** (CI-consumer workflows stay pinned to `orchestrator/free`) going + forward from 2026-09-01, regardless of how the 2026-08-30 implementation originally came to exist. + +What §10's owner authorization does **not** do is retroactively supply the specific, documented risk +acceptance ADR-0003 says is still missing: an explicit decision by someone with authority, informed by +the single-outage-domain/no-fallback trade-off ADR-0003 describes, that this risk is acceptable. §10 +directs a CI routing *policy*; it is not evidence that the owner was shown or considered that specific +availability-risk analysis when issuing it. + +**No agent may treat ADR-0003's "reverting to `orchestrator/auto`... is not foreclosed" sentence as +standing authorization to revert the CI pin today.** That sentence describes the status of the +*risk-acceptance question* (unreviewed, therefore not settled) as of ADR-0003's 2026-08-31 correction — +written *before* §10 existed. §10 is the owner's own later, explicit, binding instruction ("...로 +고정" — fixed/pinned) governing CI-consumer workflows now; an agent reverting a required-check +workflow away from it on the strength of a pre-§10 ADR sentence, without a new owner decision, would be +exactly the kind of unilateral action that produced the original 2026-08-30 incident this whole note +exists to distinguish from. The only path from here to `orchestrator/auto` is a **new owner decision +updating §10 itself** — possibly informed by the risk-specific review ADR-0003 says is still missing — +never an agent's own reading of "not foreclosed" in isolation. Until such an update lands, both records +stay true at once without conflict: the pin is owner-authorized and binding as CI-workflow policy (§10), +and the specific availability risk it carries remains open, unreviewed, and unresolved +(`AGENTS.md`, ADR-0003) — an open question about the risk is not the same as open license to change the +policy. + +**Addition (2026-09-02, second revision) — verified against current source, not merely restated:** +this revision adds three specific architectural constraints on top of the existing pin, all confirmed +true against `.github/workflows/strix.yml` and `scripts/ci/contextual_orchestrator_review_sidecar.sh` +at the time of this addition, not asserted on the strength of the directive text alone: (1) "free +후보 discovery·routing·fallback은 CO 내부에서만 한다" — confirmed: the sidecar provisions a full, +in-process `contextual-orchestrator` instance and Strix talks to it only through a locally generated +bearer token (`ORCHESTRATOR_TOKEN`/`bearer.token`); all provider discovery, routing, and free-pool +fallback happen inside that CO process, never in the calling workflow. (2) "workflow는 provider· +model·group명·유료 fallback을 지정하지 않고 gateway token만 쓴다" — confirmed, with one precision +correction (flagged by Devin Review on this PR, 2026-09-02: the workflow does write the literal string +`orchestrator/free` into `STRIX_LLM_FILE` and pass that file to Strix alongside the gateway token, so +"specifies no group name at all" overstates it): `strix.yml`'s `Gate Strix secrets` step hardcodes +`STRIX_MODEL: contextual-orchestrator/orchestrator/free`, its `case` statement rejects any +`client_payload.strix_llm` override that isn't empty or that exact same value (`::error::Strix model +overrides are limited to contextual-orchestrator/orchestrator/free.`), and its later `Prepare Strix +model input file` step (`strix.yml:732-749`) writes the single pinned constant `orchestrator/free` to +`STRIX_LLM_FILE` — the workflow has no live path to *choose* a different provider, a different concrete +model, an alternate group, or a paid fallback; it only ever relays that one hardcoded value forward, +never a raw provider credential. (3) "capability가 +없으면 유료 우회 없이 fail closed" — confirmed: the sidecar's `CONTEXTUAL_ORCHESTRATOR_POOL` validation +(`fail "CONTEXTUAL_ORCHESTRATOR_POOL must be free"` on anything but `free`) is exactly the fail-closed, +no-paid-bypass enforcement this session's own earlier "`auto` removed as an accepted value" fix put in +place (see `docs/product-technical-gap-baseline.md`). Like §10's original 2026-09-01 addition, this is +not a new technical requirement — it is the existing implementation, now made an explicit, checkable +standing instruction instead of something only discoverable by reading the sidecar/workflow source. + ## How to point a `/goal` session at this directive Because `/goal` truncates at 4000 characters, do not paste the sections above into it. Instead use a short pointer, e.g. (Korean, ~260 chars, well under the cap): ```text -/goal ContextualWisdomLab/.github의 docs/product-goal-directive.md 전문을 지침으로 삼아 실행하라. 열린 PR마다 리뷰 확인→수정→Checks 재검증→병합→다음 개발을 중간 보고 없이 반복하고, PR·Issue 소진 후에도 Gap 기반 개발을 계속한다. 이 문서의 9개 절 전체(실행 루프, 동시작업/근본수정, 연구추적성, UX/UI, 아키텍처/DB, 언어/측정, 검증/부하, LLM/오케스트레이션, 참고 라이브러리)를 매 사이클 적용 대상으로 취급하고, 이 문서와 docs/CWL-MASTER-CONTEXT.md §7이 상충하면 상충을 해소하고 두 문서를 함께 갱신하라. 한 시간 간격으로 재예약하라. +/goal ContextualWisdomLab/.github의 docs/product-goal-directive.md 전문을 지침으로 삼아 실행하라. 열린 PR마다 리뷰 확인→수정→Checks 재검증→병합→다음 개발을 중간 보고 없이 반복하고, PR·Issue 소진 후에도 Gap 기반 개발을 계속한다. 이 문서의 10개 절 전체(실행 루프, 동시작업/근본수정, 연구추적성, UX/UI, 아키텍처/DB, 언어/측정, 검증/부하, LLM/오케스트레이션, 참고 라이브러리, orchestrator/free 고정)를 매 사이클 적용 대상으로 취급하고, 이 문서와 docs/CWL-MASTER-CONTEXT.md §7이 상충하면 상충을 해소하고 두 문서를 함께 갱신하라. 한 시간 간격으로 재예약하라. ``` When this directive itself changes (the user revises a section, or an agent finds it conflicts with diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 1cc9e20313..60bd1a3792 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -94,6 +94,14 @@ flowchart LR | G-14 | release/changelog/version 증거가 각 PR에 분산되고 현재 central repo 보호 main의 release candidate가 명확하지 않다 | 운영자는 어떤 기능이 supportable release인지 확인할 수 없다 | merge 후 release readiness ledger, CHANGELOG, semantic version/tag, rollback/operability evidence를 함께 갱신한다 | | G-15 | 첨부파일 처리 경계가 제품별로 다르고, 1MB 상한은 업무 데이터와 맞지 않으며 미지원 MIME/컨테이너가 parser registry에서 명시적으로 pending/quarantine 되는지 확인되지 않았다. 현재 20MB 초과 파일 가능성과 PDF/HWP/HWPX·이미지·압축파일의 parse/sidecar 흐름을 하나의 exact contract로 묶지 못했다 | 큰 업무 첨부를 거부하거나 파싱 실패를 조용히 잃으면 고객의 메일·문서 업무가 중단된다 | naruon/newsdom-api 소유 PR에서 streaming upload, configurable bounded limit above 20MB, MIME sniffing, parser capability registry, quarantine/retry, source-position provenance, and ADR를 추가하고 size/unsupported-type/zip-bomb tests를 required evidence로 만든다 | | G-16 | Required Pingora policy treated a changed documentation PNG screenshot as UTF-8 runtime evidence | Valid UI evidence blocked otherwise valid product PRs before policy evaluation | This branch verifies bounded PNG magic before exemption while runtime paths and malformed assets continue to fail closed; protected-main delivery remains the release gate | +| G-17 | 어떤 저장소도 k6 E2E 스위트가 없고, directive §7의 p95≤20ms 전 페이지 요구가 어떤 timing boundary(서버/네비게이션/인터랙션)를 재는지도 미정의다 | "충족"의 의미가 구현마다 달라지고 회귀를 놓칠 수 있다 | naruon에서 모든 page/route를 열거하는 k6 script와 명시적 timing-boundary 정의, per-page p95 assertion, bottleneck-triage 절차를 CI에 추가한다. 상세: 본문 하단 서술 항목 | +| G-18 | LLM 호출에 단일 hardcoded timeout ceiling을 두지 않는다는 원칙은 이미 받아들여졌으나, admin이 조회·설정·해제·복원할 수 있는 감사된 override 표면은 아직 없다 | 운영자가 개별 model/pool timeout을 조정·감사할 수단이 없다 | contextual-orchestrator `/admin`에 per-model timeout CRUD·우선순위·상속·검증·감사 API를 ADR과 함께 추가한다. 상세: 본문 하단 서술 항목 | +| G-19 | i18n 번역 문자열의 저장 위치(파일/JS bundle vs versioned DB resource)가 `naruon/frontend`에서 아직 감사되지 않았다 | 8개 언어의 텍스트 팽창·CJK·locale 실패를 놓치면 고객이 잘림·겹침을 본다 | naruon/frontend의 현재 i18n 저장 방식을 감사하고, versioned DB resource·언어별 Storybook/E2E로 전환한다. 상세: 본문 하단 서술 항목 | +| G-20 | ConceptWeave/SDP/context-graph-contracts/enterprise-architecture-core의 온톨로지 파이프라인 책임 분리가 문서 인용 수준이며 이 세션의 저장소 접근으로는 교차 검증할 수 없다 | 문서상 경계와 실제 구현 경계가 다르면 온톨로지 release 신뢰성이 깨진다 | 해당 4개 저장소 접근 권한이 있는 세션이 파이프라인·의사결정 소유권 분리를 실제 코드와 대조 검증한다. 상세: 본문 하단 서술 항목 | +| G-21 | directive가 이름을 붙인 14개 저장소가 `CWL-MASTER-CONTEXT.md`의 ecosystem catalog/UML에 아직 없다 | 문서 간 불일치로 신규 에이전트·구매자가 실제 생태계 범위를 오판한다 | 각 저장소의 실제 현재 상태를 확인해 `CWL-MASTER-CONTEXT.md`의 카탈로그·UML에 추가한다. 상세: 본문 하단 서술 항목 | +| G-22 | `contextual-orchestrator`의 stdlib-Python core가 새로 sharpened된 §6 Rust 원칙(허용 예외는 ADR로 근거·범위·제거조건 명시) 기준을 충족하는지 미검증이다 | 언어 선택이 정책과 어긋나면 성능·유지보수 리스크가 문서화 없이 누적된다 | `library_research.md`의 기존 항목을 §6 신판 기준으로 재검토하고, control-plane 로직이 Rust mandate 범위에 드는지 판정한다. 상세: 본문 하단 서술 항목 | +| G-23 | directive §8의 CI 통합 아키텍처(exact-SHA 검증, owner RED→fix→GREEN→release, mutable-head 금지 등) 요구가 현재 owner/consumer 관계 전반에서 실제로 충족되는지 감사되지 않았다 | "이미 하고 있다"는 인상과 검증된 준수는 다르다 | 모든 owner PR·release·consumer 변경에 대해 SBOM/provenance/exact-SHA 검증이 실제로 걸리는지 전용 감사 pass로 확인한다. 상세: 본문 하단 서술 항목 | +| G-24 | directive §4가 Keyverse 연동으로 Direct Grant/ROPC를 허용하며 로그인·가입·복구를 제품 자체 form으로 만들라고 명시한다(owner 검증 문구, 재작성 대상 아님). ROPC는 정의상 제품 코드가 raw credential을 직접 취급해 IdP가 credential을 격리하는 redirect 기반 Authorization Code 경계를 우회한다 | 제품이 침해되면, redirect 기반 흐름이라면 격리됐을 raw credential을 공격자가 그대로 탈취할 수 있다 | 보완 통제(TLS 강제, credential 무저장·무로깅, product-side rate limit/lockout)를 Keyverse 통합 ADR로 명시한다. 대안 검토 시 embedded webview는 PKCE 여부와 무관하게 격리를 제공하지 않으므로(RFC 8252), 대안은 반드시 external user agent(system browser/Custom Tabs/ASWebAuthenticationSession) 기반이어야 한다. 상세: 본문 하단 서술 항목 | ## 4. 열린 PR live inventory @@ -2626,6 +2634,170 @@ Higgins, S. S., Crepalde, N., & Fernandes, L. (2021). Segmented multiplexity: A **Residual.** This closes the specific floating-image contribution from these three central workflows; it does not by itself guarantee the organization-wide Actions queue is fully drained, since other repositories' own workflows and any remaining unpinned central workflows may still request the floating image. Worth a follow-up sweep across the rest of `.github/workflows/` and sibling-repo workflows if queuing persists after this lands. +**Independent corroboration (this session, same day).** `ContextualWisdomLab/naruon#1486`'s `strix` required check sat `queued` for 40 minutes on `ubuntu-latest` before GitHub auto-cancelled it (workflow run `33494728480`, job started `09:55:18Z`, cancelled `10:35:22Z` with the parent run's own `status` still reported as `queued` at cancellation time — it never got a runner at all). A `rerun_failed_jobs` attempt was rejected (`403 This workflow is already running`), consistent with this entry's diagnosis: the floating-image starvation, not a scan failure or a code defect in the PR under review. No further action was taken on that PR beyond noting the cause; this fix (once merged, if not already) is expected to resolve it without any naruon-side change. + +## 2026-09-01 product-goal-directive.md revision: two new tracked, unimplemented product gaps + +The owner re-issued the full nine-section `docs/product-goal-directive.md` directive verbatim via a +`/loop` invocation (see `docs/doctoring/product-goal-directive.md`'s 2026-09-01 entry for the full +diff-against-prior-text reasoning). Two of the three genuinely new requirements introduced are +concrete, testable product gaps with no owning repository or implementation yet, recorded here per +directive §1's own instruction to derive gap/status entries from ADRs, research, current data, and PRs. + +**G-17 — E2E load-test acceptance gate (directive §7).** New requirement: every page's p95 +end-to-end processing time must be ≤ 20ms under k6 load test, checked across *all* pages (not a +sample), with any bottleneck removed and the page re-verified before the gate can pass. None of this +session's four in-scope repositories (`.github`, `noema`, `contextual-orchestrator`, `naruon`) has a +k6 E2E suite wired into CI today. `naruon` is the most plausible first owner — it is the only one of +the four with a customer-facing web surface (`frontend/`, Next.js) and an existing FastAPI backend +whose async request path this gate would exercise directly — but this has not been scoped, estimated, +or started. Needs, at minimum: a k6 script enumerating every page/route, a CI job running it against a +built `frontend`+`backend` stack, a p95-per-page assertion (not an aggregate/average), and a documented +bottleneck-triage procedure so a first failure has a defined remediation path rather than an +open-ended investigation each time. **Timing boundary undefined (flagged by Devin Review):** neither +the directive text nor this entry states what "processing time" spans — server request-received-to- +response-sent, browser navigation-start-to-load-event, or interaction-to-next-paint would each yield a +materially different number for the same page. k6's own default HTTP-request-duration metric measures +only the transport-level request/response leg, not client-side render/hydration; a future k6 suite +implementing this gate must pick and document one explicit boundary (and, if client-rendered work is +in scope, pair k6 with a browser-timing tool that measures it) so "p95 ≤ 20ms" has one unambiguous +meaning across every page and every future re-verification, rather than each implementer choosing +whichever boundary makes their own page look compliant. + +**G-18 — Admin-configurable per-model LLM timeout (directive §8).** New requirement: no application/ +agent/gateway layer may impose a single hardcoded timeout ceiling on LLM calls (default: unlimited/ +`null`); a per-model timeout becomes active only through an admin-facing web surface with full CRUD +(query/set/clear/restore), explicit units, priority, inheritance, input validation, and an audit +trail as a documented API contract, and even an admin-configured timeout must never fire as a bare +elapsed-time cutoff against an in-progress reasoning/streaming/tool-call turn — logs must distinguish +user-cancelled, provider-terminated, and admin-timed-out outcomes as three separate recorded states. +`contextual-orchestrator`'s existing `/admin` console (`contextual_orchestrator/admin.py`) is the +natural owner, since per-model/pool configuration already lives there and `orchestrator.py` already +has no fixed per-call timeout on its own primary inference path (this session's +`scripts/ci/noema_review_gate.py` transport-fix work this same day, reconciled in the 2026-09-01 +`ContextualWisdomLab/naruon#1486` entry above, independently confirms the "no uniform hardcoded timeout" direction is +already the accepted design elsewhere in the ecosystem — this gap is about giving admins an explicit, +audited *override* surface, not about reintroducing a default timeout). Not started: no ADR, no KV +schema for per-model timeout records, no `/admin` UI, no API contract. Needs an ADR before +implementation begins, given the audit-trail and priority/inheritance semantics it must get right the +first time (a later redesign would mean migrating live admin-set timeout records). + +Neither gap blocks any currently open PR; both are recorded so a future pass of this loop (or a +`spawn_task` suggestion) picks them up once the open-PR queue is exhausted, per directive §1's "PR· +Issues 소진 후에도 제품 Gap 개발과 병합 Loop를 계속한다." + +## 2026-09-02 owner-supplied control-plane facts: three more merges into the runner-queue picture + +The owner supplied fresh, directly-observed control-plane facts on `.github#1659` (this directive/ +baseline reconciliation PR) while protected `main` kept moving underneath it, with an explicit +instruction to preserve them here rather than let them get lost in a PR comment thread, and *not* to +treat any of this as license to rewrite the directive text itself (that's `docs/product-goal-directive.md`'s +job, already reconciled separately) or to transfer any predecessor check result across these SHAs. +Recorded verbatim-in-substance, each independently spot-checked against the named commit before +being written here: + +- **`#1658` (`69e80bdf...`)** — Strix's trusted job now exports `LLM_TIMEOUT=0` (this session + independently confirmed this exact line during the prior PR-merge pass on `.github#1659`, before + the owner's comment arrived — a real, concrete instance of the "no uniform hardcoded LLM timeout" + principle this same PR just added to directive §8, landing in the wild the same day the directive + text was updated to require it). +- **`#1656` (`6a25bc11...`)** — ten PR-close workflows no longer allocate a runner-backed job for + their `cancel-closed-pr-runs` step when it would be an echo-only no-op; new permanent regression + contracts distinguish those native-concurrency-group PR-stable lanes (which GitHub itself resolves + without spending a runner) from the real Noema/Strix jobs that must actually reach the GitHub API to + cancel a stale run. This is a second, independent contributor to the organization-wide queuing + problem this file's adjacent 2026-09-01 entry (floating `ubuntu-latest` image) already tracks — a + distinct root cause (wasted runner allocation for a job that never needed one at all, vs. a starved + floating image for jobs that do need one), fixed in a separate PR the same day. +- **`#1651` (`2792b964...`)** — the Bytez sidecar-integration fix this session merged into the + `contextual-orchestrator` ZDR-vendored review path: an exact-zero provider-native `meterPrice` can + now admit a Bytez route into `orchestrator/free` on explicit non-token price evidence, without + fabricating a token-based price to justify it; malformed, missing, nonzero, partial, or + contradictory pricing evidence still fails closed. `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md` + and a new focused doctoring record (`docs/doctoring/bytez-provider-meter-free-evidence-20260902.md`) + were updated in that same merge — this entry only cross-references it; the ADR/doctoring pair is + the authoritative record for *why* and *how*, not this line. + +**Queue-depth data point (do not extrapolate past what it actually shows):** `.github`'s queued +Actions depth was reported as 1,252 immediately before `#1658`/`#1656` merged, 1,280 immediately +after, and 1,282 immediately after `#1651`. Read plainly, that is *not* evidence the fixes made +things worse — the owner's own framing, preserved here rather than reinterpreted, is that **existing +queued runs are not retroactively removed by a source-level fix that only changes future behavior**: +a run already sitting in GitHub's queue when `#1658`/`#1656`/`#1651` merged keeps its old +runs-on/allocation shape regardless of what the workflow file now says, so the visible depth number +keeps climbing on its own inertia for a while even after the root causes stop adding *new* waste. +The owner's own stated acceptance criterion, recorded here so a future pass doesn't invent a +different one: measure the **future stale/no-op admission rate** and **current-head throughput** +going forward from these three merges, not the raw queue-depth number at any single point in time — +an instantaneous depth drop was never the right signal to wait for. + +**Cross-reference, not a duplicate:** this entry supplements, and does not restate or supersede, the +2026-09-01 "floating runner image" entry above (still the record for the `ubuntu-latest` → +`ubuntu-24.04` pin across `strix.yml`/`opencode-review.yml`/`noema-review.yml`) and the "independent +corroboration" paragraph appended to it (`ContextualWisdomLab/naruon#1486`'s `strix` check queued-then-cancelled +observation). Together the two entries are the current, most-complete picture of why Actions runners +across this organization were saturated through early 2026-09-01/02, and what has been fixed so far. + +## 2026-09-02 product-goal-directive.md second revision: three new tracked gaps, one tracked doc-sync follow-up + +The owner re-issued the full ten-section `docs/product-goal-directive.md` directive again as a chat +message (see `docs/doctoring/product-goal-directive.md`'s 2026-09-02 entry for the full +section-by-section diff reasoning). Three of the five substantively-expanded sections introduce +concrete, currently-unimplemented product/process gaps worth tracking here per directive §1's own +instruction; a fourth item is a documentation-sync gap (a set of ecosystem repos this directive now +names that `docs/CWL-MASTER-CONTEXT.md`'s own catalog does not yet carry), not a product gap. + +**G-19 — i18n translation ledger must be a versioned DB resource (directive §4).** New requirement: +any customer-facing UI's translation strings must live in a **versioned DB resource**, never static +files or a JS bundle; server/native code fetches only the current screen's keys with caching, the +browser is never handed the whole catalog or heavy i18n JavaScript, and no SPA architecture may be +assumed. Eight languages are named (한국어·영어·일본어·중국어·베트남어·스페인어·독일어·프랑스어 — +ko/en/ja/zh/vi/es/de/fr), each requiring its own Storybook/E2E pass checking for width/wrap/CJK/ +text-expansion/font-fallback/locale-format failures (truncation, overlap, meaning-loss), not a single +default-locale screenshot. If no shared translation-management product exists, a new repository must +provide per-product translation review/approval/deploy/rollback API plus an admin UI. **Not audited +in this pass:** whether `naruon/frontend` (the only customer-facing web surface among this session's +four in-scope repos — `.github`, `noema`, `contextual-orchestrator`, `naruon`) currently stores its +i18n strings as files/bundle (the likely default for a Next.js app scaffolded without this +requirement in mind) or already meets this bar. That audit is deliberately deferred to a dedicated +future Gap increment — this entry only records the requirement and its current unverified-compliance +status, consistent with directive §1's "one Gap increment at a time" philosophy. + +**G-20 — Ontology-pipeline repo-responsibility split needs a cross-check, not just a citation +(directive §5).** New requirement: ConceptWeave owns the +observe→discover→propose→align→validate→review→publish pipeline and semantic release; SDP owns +catalog/governance/consumption; context-graph-contracts owns interop contracts; +enterprise-architecture-core owns the Context Map and cross-cutting decisions. Released +concepts/relations/dimensions/measures/mappings must carry evidence/provenance/validity/confidence/ +status/deprecation/locale-label metadata; consumers may use only released API/contract/ACL (no file +copies, no cross-service SQL, no unapproved publication); the UI translation ledger (G-19, above) +and the ontology label ledger must never share a store. This session could confirm `semantic-data-portal`'s +role against its existing `docs/CWL-MASTER-CONTEXT.md` description (consistent, additive), but could +**not** reach `ConceptWeave`, `context-graph-contracts`, or `enterprise-architecture-core` (outside +this session's repository scope) to confirm the pipeline/decision-ownership split actually matches +what those repos currently implement, or whether the immutable-release metadata contract is already +enforced anywhere. Needs a follow-up pass with access to those three repos before treating this split +as verified rather than merely recorded. + +**G-21 — `docs/CWL-MASTER-CONTEXT.md` ecosystem catalog is missing 14 repo names the directive now +uses (directives §5, §9).** `ConceptWeave`, `context-graph-contracts`, `enterprise-architecture-core`, +`EgressWeave`, `OriginWeave`, `pingora-gateway`, `quarantine-sandbox-runtime`, `EmbedRelay`, +`DiagramWeave`, `mhtml-etl-gateway`, `psychometrics-commons`, `PolicyWeave`, `CalendarWeave`, and +`supply-chain-control-plane` are all named with specific responsibilities in the 2026-09-02 +`product-goal-directive.md` revision, but none of the fourteen appears in `CWL-MASTER-CONTEXT.md`'s +own ecosystem catalog or UML diagram as of this entry. This is a documentation-sync gap, not +necessarily a missing-implementation one — several of these repos may already exist and do exactly +what the directive says, simply undocumented in the master-context file yet. Needs: an agent (or the +owner) with access to these repos to confirm each one's actual current state, then add matching +entries to `CWL-MASTER-CONTEXT.md`'s repo catalog and ecosystem UML so the two documents stay +consistent — this session's repository access (`.github`, `noema`, `contextual-orchestrator`, +`naruon`) does not extend far enough to do that confirmation itself. + +None of these three gaps blocks any currently open PR; all are recorded so a future pass of this loop +(or a `spawn_task` suggestion, repository access permitting) picks them up once the open-PR queue is +exhausted, per directive §1's "PR·Issues 소진 후에도 제품 Gap 개발과 병합 Loop를 계속한다." G-20 and +G-21 are the same underlying documentation-completeness issue seen from two angles (pipeline-role +verification vs. catalog-entry existence) and should likely be closed by the same follow-up pass. ## 2026-09-02 GitHub Actions review sidecar pool pinned to `orchestrator/free`; `auto` removed as an accepted value **Problem.** `scripts/ci/contextual_orchestrator_review_sidecar.sh` — the script every central required review workflow (Strix, OpenCode Review, Noema Review, the PR-review autofix sidecar) provisions to talk to `contextual-orchestrator` — read an operator-settable `CONTEXTUAL_ORCHESTRATOR_POOL` environment variable, defaulted it to `free`, and validated it against exactly two accepted values: `free` or `auto` (`case "$orchestrator_pool" in free|auto) ...`). `auto` is a real, load-bearing value one layer down: `scripts/ci/contextual_orchestrator_review_launcher.py --pool auto` admits *priced* discovered routes as a fallback stage once the free pool is exhausted (`build_zdr_prioritized_catalog(..., pool="auto")`), by design, for callers that want that behavior. Nothing in this repository's own review-provisioning code path currently sets `CONTEXTUAL_ORCHESTRATOR_POOL=auto` — the only workflow that sets the variable at all, `strix.yml`, sets it to `free`; every other central review workflow simply relies on the script's own `:-free` default — so this was not a live incident, it was an unaudited, structurally-reachable escape hatch: a future edit to any of the four workflows above, or a manually-triggered `workflow_dispatch` with a custom env override, could set `CONTEXTUAL_ORCHESTRATOR_POOL=auto` and the sidecar would accept it silently, with no cost ceiling, no budget/authorization gate, and no reviewer visibility that priced models were now in scope for a required check. @@ -2649,6 +2821,89 @@ Higgins, S. S., Crepalde, N., & Fernandes, L. (2021). Segmented multiplexity: A **Follow-up.** If the organization later solves free+ZDR routing robustly enough to deliberately widen required-review CI to `orchestrator/auto` (e.g. once a spend ceiling and reviewer-visible cost evidence exist for that path), the change is exactly one `case` arm plus the corresponding assertions in `test_sidecar_pins_the_pool_to_free_for_github_actions` — this entry is the record of *why* it was narrowed, not a permanent prohibition. +## 2026-09-02 `.github#1659` reconciled with `main` (15 commits behind); no new gap, process note only + +**Observed.** This directive/baseline-reconciliation PR's branch +(`docs/update-product-goal-directive-2026-09-01`) had drifted 15 commits behind `main` while still 6 +ahead (its own doc-only commits), and its own CI run showed 11 failing tests, all in contract-test +files this PR never touches (`test_current_head_run_coalescer.py`, +`test_merge_scheduler_runner_image_contract.py`, `test_opencode_live_draft_state_regression.py`, +`test_opencode_required_verdict_regression.py`, `test_queue_cancellation_scheduler_contract.py`, +`test_required_security_runner_image_contract.py`, `test_required_workflow_queue_contract.py`, +`test_strix_llm_timeout_contract.py`). Confirmed by branch-divergence count (`git rev-list +--left-right --count origin/main...HEAD` → `15 6`) that these were pre-existing test/workflow drift +from `main` moving forward underneath this branch (the `ubuntu-24.04` runner-image pin, the +`LLM_TIMEOUT=0` Strix change, the hourly-review-repair single-file consolidation, and others already +recorded above), not a regression this PR's doc-only commits introduced. + +**Fix.** Ordinary `git merge origin/main` (no rebase, no force-push, per this session's standing +policy) into the PR branch. One conflict, in this same file (`docs/product-technical-gap-baseline.md`) +— both sides had appended new dated sections after the same anchor paragraph; resolved by keeping both +sections in sequence (this file is append-only by convention, so no content was dropped or +reinterpreted, only the marker lines removed). Re-ran the 8 previously-failing files after the merge: +`PYTHONPATH=. python3 -m pytest <8 files> -q` → **177 passed**. Pushed the merge commit +(`21ea46c4`) to the PR branch and converted the PR from draft to ready-for-review. + +**Not a new gap.** Recorded here only as a process note (branch-staleness reconciliation, not a +product or security gap) since the standing directive's §1 instructs deriving gap/status updates from +PRs encountered during the loop, and a future pass hitting the same "PR branch stale behind main, its +own unrelated contract tests failing" pattern on any other long-lived PR should reach for the same +diagnosis (check `git rev-list --left-right --count origin/...HEAD` before assuming a real +regression) rather than re-investigating from scratch. + +## 2026-09-02 product-goal-directive.md third revision: two audit gaps deferred, not fabricated + +The owner re-issued the full directive a third time overall (second time this same day) as a genuine +chat-turn message. Most of the revision's new content is process/convention text with no product-gap +shape (a PR close/repair taxonomy in §2, a naming-scope widening in §5, a Python-exception rule in §6, +a "core foundation" definitional framing in §9) or content this session directly verified against live +source before recording (§10's CO pool-pin elaboration, confirmed true against `strix.yml` and +`scripts/ci/contextual_orchestrator_review_sidecar.sh`). Two pieces of new content are genuine, +currently-unverified audit gaps, recorded here rather than either asserted as already-compliant or +silently dropped: + +**G-22 — `contextual-orchestrator`'s stdlib-Python core against the newly sharpened §6 Python rule.** +§6 now states plainly that Python is disfavored and must never be chosen for LLM/agent-tooling +convenience, with exactly one permitted exception (a Python-only ML runtime with no practical Rust +alternative for that specific part, scope/rationale/removal-condition recorded in an ADR, hot path +still in Rust). `contextual-orchestrator`'s own `CLAUDE.md` describes it as "a stdlib-Python lab" for +its core control-plane (HTTP routing, delegation, verification, synthesis) — not itself the +"수리과학·Psychometrics·EDA·데이터과학 core 연산" this section's Rust mandate names first, but plausibly +within its broader "속도·안정성·보안이 중요한 일반 소프트웨어" net, since it is the org's central, +security-critical LLM gateway. Checked, not assumed: `contextual-orchestrator/docs/library_research.md` +already exists and actively records Python-vs-Rust decisions per subsystem via the repo's own +"Ponytail design gate," and the one genuinely numeric hot path already found here — LLM token +accounting — already uses Rust (PyO3 + `tiktoken-rs`, per ADR 0006 and the corresponding +`library_research.md` rows), not Python. **Not verified in this pass:** whether the rest of that +file's existing entries meet the newly sharpened bar (an explicit ADR with scope/rationale/removal- +condition, specifically framed as *the* permitted Python exception, not just a general dependency- +research note), and whether the control-plane/orchestration logic itself is even in scope of the Rust +mandate at all — that reading is genuinely ambiguous between "core computation" (clearly out of scope +for the HTTP-routing/dispatch parts) and "general software where speed/stability/security matter" +(plausibly in scope, given what this repo *is* to the org). Needs a dedicated future pass, with a +close read of `contextual-orchestrator`'s existing ADRs and `library_research.md` against this +revision's exact §6 text, before treating this as either compliant or a violation. + +**G-23 — §8's CI integration architecture, not yet audited for compliance.** §8 gained a detailed +CI integration architecture requirement this revision (`.github` reusable-workflow-plus-thin-caller +composition; exact-SHA verification of build/API-schema-contract/E2E/model-behavior/security/SBOM/ +provenance on every owner PR/release/consumer change; owner-side RED→fix→GREEN→release with a consumer +version bump on defects; a ban on mutable-head/branch-URL/cross-repo-source/workflow duplication; an +owner-issue-plus-expiration/deletion condition on any transitional bridge). This matches this repo's +own already-documented conventions in spirit (`CLAUDE.md`'s "product hourly callers stay thin," the +central-required-workflow architecture `docs/org-required-workflow-rollout.md` already describes, +`pr-review-autofix.yml`'s vendored-sidecar-with-exact-SHA-pin pattern), so it is *plausibly* already +substantially met — but this reconciliation pass recorded the requirement directly from the directive +text and verified only §10's narrower pool-pin claims against live source, not this broader multi- +dimensional CI-contract claim against every current owner/consumer relationship in the ecosystem +(e.g., whether SBOM/provenance is actually checked on every `contextual-orchestrator` consumer change, +not just central review workflows). Needs a dedicated future audit pass before either claiming full +compliance or opening a remediation PR. + +Neither gap blocks any currently open PR; both are recorded so a future pass (or a `spawn_task` +suggestion) picks them up, per directive §1's "PR·Issues 소진 후에도 제품 Gap 개발과 병합 Loop를 +계속한다." + ## 2026-09-02 org-queue-sweep investigation: historical conclusion superseded by PR #1821 **Current status (2026-09-04).** The conclusion below was invalidated by live queue evidence. PR #1821 removed the organization-wide Actions-run inventory and cancellation block from `org-queue-sweep` and merged as `11bb6a7871f4d95ab8a3eab616b4264d02327010`. Native per-PR concurrency and the current-head coalescer now own stale-run cancellation; the scheduled sweep retains only missed review, merge, and branch-update recovery. Focused ownership contracts passed 78 tests before merge. This preserves the event-gap recovery described below without paying the repository-wide run-listing and cancellation API cost. @@ -2688,6 +2943,67 @@ Both changes explicitly documented, in the workflow file itself and in doctoring **Evidence / acceptance.** Permanent tests forbid retry/deadline/sampling symbols in the caller and prove one gateway request, one attempt annotation, control-character-safe telemetry, missing-value rejection, valid trailing-comma normalization, and exact changed-line guidance. Fresh exact-head repository checks and reviews remain the admission authority; predecessor-head evidence is not transferable. The remaining runtime work is to preserve distinct `request_too_large`, discovery, rate-limit, provider transport, malformed-output, stale-head, and sandbox-command-timeout categories in hosted logs. +## 2026-09-02 G-24: Keyverse Direct Grant/ROPC mandate hands raw credentials to product-owned login forms (flagged by Devin Review, security) + +**Problem.** `docs/product-goal-directive.md` §4's verbatim owner directive states: "Keyverse는 인증 +backend로 유지하되(Direct Grant/ROPC 또는 Keycloak REST API), 로그인·가입·복구는 제품 자체 form으로 +만든다" (Keyverse stays the auth backend via Direct Grant/ROPC or the Keycloak REST API, but +login/signup/recovery are the product's own forms, not a Keyverse-hosted page). Devin Review correctly +identified a real, previously-untracked security trade-off in this: the OAuth2 Resource Owner Password +Credentials grant (ROPC/"Direct Grant") is defined by having the *client application itself* collect +the user's raw password and forward it to the identity provider for a token — unlike a redirect-based +Authorization Code flow, where only the identity provider's own hosted page ever sees the raw +credential. This is precisely why OAuth 2.0 security best-practice guidance (RFC 6819; the OAuth 2.0 +Security Best Current Practice) treats ROPC as legacy/discouraged: it collapses the very isolation +boundary — "the product never touches raw credentials" — that a redirect-based flow provides. If any +product in this ecosystem, or Keyverse itself, currently relies on that isolation as a stated security +property ("passwordless identity boundary"), a compromised product surface (XSS, a malicious +dependency, a logging bug) could now capture raw credentials that flow would have kept out of its +reach entirely. + +**Verified before recording.** Checked `docs/adr/` and this file for any existing ADR or gap entry +covering Keyverse's credential-handling posture or a "passwordless identity boundary" claim — none +exists (`grep -rln "ROPC\|Direct Grant\|passwordless" docs/adr/` and `grep -n "Keyverse\|ROPC"` on this +file both return no prior coverage beyond an unrelated CI-automation PR reference). So this is a +genuine, newly-surfaced gap, not a duplicate of tracked work. + +**Why not fixed by editing the directive.** This sentence sits inside the owner's verbatim `>` +blockquote, and this file's own governance clause (and this session's standing practice throughout +this PR) forbids rewording verbatim owner-directed text — doing so would be substituting this +session's judgment for an explicit, deliberate owner architecture decision (the directive names *both* +Direct Grant/ROPC and the Keycloak REST API specifically, precisely because both allow a +product-branded, non-redirected login UI, which is very likely the actual reason for choosing them over +Authorization Code + redirect despite the well-known trade-off). Overriding that by editing the quote +would be presumptuous, not a fix. + +**Recorded instead, as G-24 above.** The register row captures the trade-off and a compensating-control +direction (enforce TLS on every ROPC exchange; never log or persist the raw credential beyond the +immediate token exchange; rate-limit/lockout the product-side ROPC endpoint against credential +stuffing) that a future Keyverse-integration ADR should make an explicit, reviewed decision about — +accepting the risk with documented compensating controls, or revising the integration pattern — rather +than leaving the trade-off implicit and undocumented as it was before this pass. + +**Correction (flagged by Devin Review, round 7):** this entry's first draft additionally suggested +"a PKCE-based Authorization Code flow inside an embedded/native webview" as a lower-risk alternative. +That conflates two orthogonal OAuth protections and is wrong as stated: PKCE protects the *authorization +code exchange* from interception/replay by a different, malicious app on the same device — it says +nothing about who can see the *login page itself*. An **embedded** webview is still rendered inside, +and fully inspectable by, the hosting product's own process (cookies, DOM, injected JS, form field +values) — it provides no isolation between the login form and the product at all, PKCE or not, which +is exactly why RFC 8252 ("OAuth 2.0 for Native Apps") explicitly recommends against embedded/in-app +webviews for this reason and requires the **external user agent** instead — the system browser, or an +OS-mediated in-app-browser-tab construct that runs in a separate, product-inaccessible process/cookie +jar (`SFSafariViewController`/`ASWebAuthenticationSession` on iOS, Chrome Custom Tabs on Android). If a +future ADR wants an alternative to ROPC's raw-credential handling, that alternative is Authorization +Code + PKCE **via the external user agent**, not an embedded webview with PKCE — the webview choice is +what determines isolation, not the presence of PKCE. + +**Verification.** `grep -rln "ROPC\|Direct Grant\|passwordless" docs/adr/` → no matches (confirms gap +was genuinely untracked); `docs/product-goal-directive.md`'s §4 blockquote left byte-for-byte +unchanged (`git diff` shows only the new G-24 register row and this narrative section, no change to +`product-goal-directive.md`); `PYTHONPATH=. python3 -m pytest tests/test_product_technical_gap_baseline.py -q` +→ 5 passed. + ## 2026-09-02 `test_strix_quick_gate.sh` stale cron assertion left broken by the `#1630` cadence lengthening **Problem.** The required `exact-head-path-policy` check (which runs `bash