Skip to content

docs(adr): correct ADR 0036 status — admin_ui/ is an unwired scaffold, not delivered work - #960

Merged
seonghobae merged 4 commits into
mainfrom
fix/hollow-adr-0036-admin-ui
Sep 1, 2026
Merged

docs(adr): correct ADR 0036 status — admin_ui/ is an unwired scaffold, not delivered work#960
seonghobae merged 4 commits into
mainfrom
fix/hollow-adr-0036-admin-ui

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Hollow-path finding

Org-wide audit finding (response to "빈 깡통 경로 너무 많다.."): ADR 0036 (admin UI) is marked Accepted but admin_ui/ is the untouched starter template.

docs/planning/adrs/0036-embedded-react-storybook-admin.md (status: Accepted, 2026-08-27) says the Python backend "will eventually serve the compiled static assets" of an embedded React+Storybook frontend. Independently re-verified against current origin/main:

  • admin_ui/ is exactly the unmodified Vite react-ts + Storybook scaffold output — default App.tsx ("Get started" counter demo), default Button/Header/Page stories, default react.svg/vite.svg assets.
  • Zero references to admin_ui anywhere else in the repo except pnpm-lock.yaml/pnpm-workspace.yaml (package-manager bookkeeping, not build/serve wiring).
  • No workflow under .github/workflows/ builds, lints, or tests it (no Corepack/pnpm install step, no vite build, no build-storybook).
  • contextual_orchestrator/server.py and contextual_orchestrator/__main__.py have zero references to admin_ui, a static-asset directory, or serving anything besides admin.py's ADMIN_HTML.
  • contextual_orchestrator/admin.py (1779-line inline-JS admin console) is unchanged and remains the entire /admin surface actually served.

Additionally found while verifying: ADR 0036 was never reconciled with ADR 0033 (accepted 2026-08-23, four days earlier), which deliberately keeps the console as inline stdlib HTML and defers a React/Storybook toolchain until one of three explicit triggers is met (second reusable screen family, second consuming repo, or a new component-based frontend need). None of those triggers has been met, and docs/product-technical-gap-baseline.md §6/§9 already treat ADR 0033's deferral as the operative decision ("This repository is a backend stdlib lab and has no frontend/Storybook tree"). So this wasn't just an unstarted scaffold — it's an unstarted scaffold whose ADR silently contradicts an already-accepted sibling ADR governing the same surface.

Fix

This needed a product decision, not a mechanical one. Building out admin_ui/ (CI build step + server.py static-asset serving, replacing admin.py) would reopen and override ADR 0033's reasoned, triggered deferral unilaterally — out of scope for an automated hollow-path fix. Instead, corrected ADR 0036 itself (docs-only, single file):

  • Frontmatter status: acceptedproposed.
  • ## Status: now explains the downgrade and links ADR 0033.
  • New ## Implementation Status section: states precisely what exists today (unmodified scaffold, no CI wiring, no server wiring, admin.py still serving) so this can't silently regress into "hollow" again.
  • New ## Path to Acceptance section: re-promotion requires either meeting one of ADR 0033's explicit triggers and actually building/wiring admin_ui/, or a fresh ADR that explicitly reconciles the two — not a silent re-acceptance.
  • related: frontmatter now cross-references ADR 0033 as conflicting.
  • Original Context/Decision/Consequences text preserved as the historical record of what was decided; only tense/claims corrected where they overstated progress.

No code changes. Scoped to exactly this finding — did not touch admin_ui/, ADR 0033, or docs/product-technical-gap-baseline.md (the latter's narrative section 1167-1168 also slightly overstates this as "delivered"; flagged as a separate follow-up, not fixed here, to keep this PR minimal).

Validation

  • tests/test_planning_adr_identifiers.py, tests/test_paper_contracts.py, tests/test_repository_security_metadata.py — pass (frontmatter id/heading consistency preserved).
  • interrogate — 100% (docs-only change, no Python touched).
  • coverage run -m pytest tests --ignore=tests/fuzz -x — 1903 passed, 1 pre-existing unrelated failure (tests/test_privacy_policy_analysis.py::test_pinned_mcp_client_renders_and_closes_camoufox_tab, an AttributeError: mcp module has no attribute 'Client' from an installed-mcp-package/version mismatch in this sandbox). Reproduced identically on unmodified origin/main via git stash — confirmed pre-existing and unrelated to this change, not introduced by it.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com


Generated by Claude Code

…, not delivered work

ADR 0036 was accepted 2026-08-27 claiming the Python backend "will
eventually serve the compiled static assets" of an embedded
React+Storybook admin frontend. An org-wide hollow-path audit
(2026-08-31) confirmed admin_ui/ is still the completely unmodified
Vite react-ts + Storybook starter template (default App.tsx,
Button/Header/Page stories, default react.svg/vite.svg assets), with
zero references to it anywhere in the repo outside the ADR and the
directory itself (excluding pnpm-lock.yaml/pnpm-workspace.yaml
bookkeeping). No CI workflow builds it, and server.py/__main__.py have
no static-asset-serving wiring. contextual_orchestrator/admin.py
remains the entire, unchanged /admin surface actually served.

The ADR also went unreconciled with ADR 0033 (accepted 2026-08-23),
which deliberately keeps the console as inline stdlib HTML and defers
a React/Storybook toolchain until one of three explicit triggers is
met — none of which has been met.

Downgrade status from Accepted to Proposed, add an Implementation
Status section documenting the gap precisely, cross-reference ADR
0033, and add a Path to Acceptance section so re-promoting this
decision requires either meeting ADR 0033's triggers and actually
building/wiring admin_ui/, or a fresh ADR that explicitly reconciles
the two. No code changes; docs-only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Gs7KmNvH75nxz1sL8mKjw
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: f7fb270c-7833-47a6-8e9c-00fd35725b11

📥 Commits

Reviewing files that changed from the base of the PR and between c6c3a0c and ae57631.

📒 Files selected for processing (2)
  • docs/planning/adrs/0036-embedded-react-storybook-admin.md
  • docs/product-technical-gap-baseline.md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as ready for review August 31, 2026 08:19
devin-ai-integration[bot]

This comment was marked as resolved.

…file)

Devin review on PR #960 correctly flagged that the "None of the above has
been executed beyond scaffolding step 1" line understated progress: root
package.json declares a Corepack packageManager pin (pnpm@11.24.0+...) and
pnpm-lock.yaml is checked in with a resolved admin_ui workspace entry —
decision item 2 is done. Items 3 (Storybook component development) and 4
(backend serving compiled assets) remain unexecuted. Updates the Status,
Implementation Status, and Decision sections to say so precisely instead of
the previous blanket "none of the above" / "no part of the Decision" claims.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Gs7KmNvH75nxz1sL8mKjw

Copy link
Copy Markdown
Contributor Author

noema-review crashed on this head (9f732f5) with an unhandled exception — not caused by this PR's diff (an ADR doc correction has no bearing on LLM response parsing):

File "scripts/ci/noema_review_gate.py", line 495, in extract_json_object
    return json.loads(stripped)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 978 (char 977)

The reviewer LLM returned a response that wasn't valid JSON, and extract_json_object crashes the whole job with a raw traceback instead of failing closed cleanly — a real robustness gap in the shared review script that any PR could hit whenever the model's output happens to be malformed. This is not specific to #960; dispatched a fix for the underlying script (currently investigating whether the canonical source is .github or a local copy here). Re-running the failed job once now, since the underlying LLM-output condition is non-deterministic and may not recur on retry even before that fix lands.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Required noema-review check failure — not this PR's

The noema-review check failed on head 924c0932ab76a3b9230adab827c08a52b0a0ae93 with:

RuntimeError: Noema reviewed line 1 is not an exact changed-side line
...
TimeoutError: timed out

Root cause (confirmed, not this PR's diff): noema-review is a required central workflow. Per ContextualWisdomLab/.github's own policy, it materializes scripts/ci/noema_review_gate.py from .github's trusted main branch into every target repo's runner — this repo has no local copy of that script or of noema-review.yml. The version currently on .github's main (commit 1cbb6aaf) still calls the LLM gateway with a raw timeout=120 on the JSON-repair retry path; when the first verdict needs one repair attempt and the retry is slow, the hard 120s socket timeout fires before the response completes, crashing the check.

This is already fixed, just not merged yet: ContextualWisdomLab/.github#1507 (open, base = current main) raises this to a proper deadline-bounded 2-hour budget (LLM_REQUEST_TIMEOUT_SECONDS/LLM_REQUEST_TOTAL_BUDGET_SECONDS) computed fresh on every call_llm attempt including the repair retry, plus a watchdog that fails closed instead of hanging. All 29 Devin Review findings raised against that PR across its many rounds are now resolved or confirmed as intended behavior; it's passing CI and just finishing its own required-review cycle before the merge scheduler can pick it up.

Nothing to widen or change in this PR — once .github#1507 merges, the next noema-review dispatch on this PR's current head will run the fixed script. Re-running now would very likely hit the same deterministic timeout again (the base script hasn't changed), so I'm holding off on a re-run until #1507 lands, and will keep this PR watched in the meantime.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Required opencode-review check failure — also not this PR's

Separate from the noema-review timeout I reported earlier: the opencode-review required check polled for ~91 minutes (18:26–19:57) and never saw an APPROVED/CHANGES_REQUESTED verdict from opencode-agent on this PR's current head:

::error::No APPROVED or CHANGES_REQUESTED from opencode-agent on the current head.

This is a central review-dispatch pipeline issue, not something in this PR's diff — ContextualWisdomLab/.github#1507 (the same PR fixing the noema-review timeout) is also actively working the OpenCode review-dispatch pipeline's timing/budget right now (poller-budget and cross-check fixes in progress). Holding off on a re-run here for the same reason as before — will pick back up once the central review pipeline fixes land.


Generated by Claude Code

@seonghobae

Copy link
Copy Markdown
Contributor Author

Cross-PR integration contract: routing identity is provider-neutral model_group only; do not add or preserve a provider-family abstraction. OpenRouter discovery must retain concrete free model IDs, while the aggregate openrouter/free router is not a serving candidate. OpenCode, Noema, and Strix must call contextual-orchestrator. Do not impose fixed wall-clock deadlines on inference, initial ping, readiness/health, provider discovery, or OpenRouter ZDR-list retrieval; use explicit cancellation and evidence-backed transport failure instead. Reconcile this PR with #971 and central .github #1508 before merge.

Copy link
Copy Markdown
Contributor Author

Checked this PR's diff against #971's for the cross-PR contract above. Both touch docs/product-technical-gap-baseline.md, but in disjoint sections: this PR only corrects the ADR 0036 (admin UI) narrative and its P2 gap-table row, while #971's edits to that file are confined to the separate noema-review-timeout/"GAP RESOLVED" narrative further down. No shared paragraph, and this is a docs-only ADR-status correction that doesn't independently touch model_group/OpenRouter-discovery/deadline logic — ordinary rebase-when-it-lands, no reconciliation changes needed here.


Generated by Claude Code

@seonghobae

Copy link
Copy Markdown
Contributor Author

Contextual-Orchestrator와 관계한 것들을 같이 손보든 어쩌든 해결하세요. Bypass merge 필요하면 가능 (chicken and eggs 상황이라면) + NVIDIA NIM 만 쓰는 건 허용하지 않아요. Contextual-Orchestrator를 쓰세요. Timeout은 적어도 3시간으로 잡으세요. 120초 같은 건 당황스럽군요.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Contextual-Orchestrator와 관계한 것들을 같이 손보든 어쩌든 해결하세요. Bypass merge 필요하면 가능 (chicken and eggs 상황이라면) + NVIDIA NIM 만 쓰는 건 허용하지 않아요. Contextual-Orchestrator를 쓰세요. Timeout은 적어도 3시간으로 잡으세요. 120초 같은 건 당황스럽군요. Strix가 6시간 이상 동작해서 취약점 잡는 것도 본 일이 있습니다. Opencode와 Noema 는 Coderabbitai 및 Devin 수준으로 실제로 리뷰를 하게 하시오. Strix도 보안 리뷰를 꼼꼼하게 하도록 하시오. 특히 보안 리뷰는 전체 코드로 수행하는 것입니다. Contextual-Orchestrator는 실시간으로 빠르면서 능력이 좋은 모델에 요청을 보내어 시간을 당기시오. @opencode-agent 라고 부르면 호출되는 기능도 인터넷 가이드에는 /oc 라고 나와있기 때문에 이 점도 확인해 보는 게 좋겠습니다.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head audit of 924c0932ab76a3b9230adab827c08a52b0a0ae93 found one ADR lifecycle inconsistency and corrected it in ae5763126ff959ba19e3178f70a4e6f5820ec8d4. PR #893 did formally accept ADR 0036 and merge it, so incomplete implementation cannot retroactively make the decision merely proposed. Because this PR reinstates ADR 0033 as the operative decision, ADR 0036 is now recorded accurately as accepted on 2026-08-27 and superseded on 2026-08-31. The scaffold facts remain verified: admin_ui source is byte-identical to merge commit 7cab1f27, no workflow builds/tests it, no server path serves it, and /admin remains the 1,779-line inline ADMIN_HTML. Focused ADR identifier test passed and git diff --check is clean. Prior Noema/OpenCode failures are hosted review-pipeline failures (Noema invalid changed-line verdict then retry timeout; OpenCode no current-head verdict), not documentation/test failures.

Copy link
Copy Markdown
Contributor Author

noema-review failed again — this is the same central-infra crash this PR itself was cited as the original evidence for in ContextualWisdomLab/.github#1507's bug report: scripts/ci/noema_review_gate.py:656's opener.open(request, timeout=120) hitting a raw, unhandled TimeoutError. That file is canonical only in .github and materialized fresh into this repo's runner, so it can't be patched from here.

.github#1507 (still open, not yet merged) removes this exact 120-second hard stop. Once it merges, this repo's next noema-review run picks it up automatically. Watching #1507 to green; will re-check this PR once it lands. (Same failure also hit #958 and #963 this session — already noted there.)


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Update: after .github#1507 merged, noema-review no longer crashes on this PR — it now runs to completion and hits a different, legitimate fail-closed rejection: "Noema reviewed line 1 is not an exact changed-side line". This is noema_review_gate.py's intentional anti-hallucination guard (validate_substantive_verdict) rejecting a verdict whose cited (path, line, side) didn't exactly match a real line in the diff — working as designed, not a bug. This looks like an LLM output-quality miss on this specific attempt rather than a systemic issue (two other PRs, contextual-orchestrator#963 and .github#1476, both got clean noema-review approvals around the same time). Queued a re-run for a fresh attempt.


Generated by Claude Code

@seonghobae
seonghobae merged commit 34a8f81 into main Sep 1, 2026
31 of 34 checks passed
@seonghobae
seonghobae deleted the fix/hollow-adr-0036-admin-ui branch September 1, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants