> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 04-1 CLAUDE.md and Memory Files: Purpose, Optimization, Length, Format

> CLAUDE.md is context, not enforced configuration. This unit unpacks the four placement locations, the cross-task leverage filter, modular file splitting, the division of labor with auto-memory, and a cross-tool comparison of project-level instruction file names.

export const ToolCompare = ({lang = "zh", tools = [], dimensions = [], defaultSelected, notes = []}) => {
  const UI = lang === "en" ? {
    allTools: "All",
    recommend: "Recommended",
    noSupport: "N/A",
    minOneToolW: "Select at least one tool",
    mobileLabel: "Tool",
    dimensionLbl: "Dimension",
    notes: "Notes"
  } : {
    allTools: "全選",
    recommend: "推薦",
    noSupport: "無對應",
    minOneToolW: "至少選一個工具",
    mobileLabel: "工具",
    dimensionLbl: "維度",
    notes: "注意事項"
  };
  const ACCENT_L = "#bf7551";
  const ACCENT_D = "#cf8a68";
  const REC_BDR_L = "rgba(191,117,81,0.45)";
  const REC_BG_L = "rgba(191,117,81,0.06)";
  const REC_BDR_D = "rgba(207,138,104,0.45)";
  const REC_BG_D = "rgba(207,138,104,0.08)";
  const looksLikePath = val => typeof val === "string" && (/[/\\.*:]/).test(val);
  const safeTools = Array.isArray(tools) ? tools : [];
  const safeDimensions = Array.isArray(dimensions) ? dimensions : [];
  if (safeTools.length === 0 || safeDimensions.length === 0) return null;
  const allIds = safeTools.map(t => t.id);
  const initSelected = Array.isArray(defaultSelected) && defaultSelected.length > 0 ? defaultSelected.filter(id => allIds.includes(id)) : allIds;
  const [selectedIds, setSelectedIds] = useState(initSelected.length > 0 ? initSelected : allIds);
  const [expandedCell, setExpandedCell] = useState(null);
  const [mobileTool, setMobileTool] = useState(initSelected[0] || allIds[0]);
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const detect = () => setIsDark(document.documentElement.classList.contains("dark"));
    detect();
    const obs = new MutationObserver(detect);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => obs.disconnect();
  }, []);
  const toggleTool = id => {
    setSelectedIds(prev => {
      const next = prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id];
      if (next.length === 0) return prev;
      if (expandedCell) {
        const [, cellToolId] = expandedCell.split(":");
        if (!next.includes(cellToolId)) setExpandedCell(null);
      }
      return next;
    });
  };
  const isAllSelected = selectedIds.length === allIds.length;
  const toggleAll = () => {
    if (isAllSelected) {
      setSelectedIds([allIds[0]]);
    } else {
      setSelectedIds(allIds);
    }
    setExpandedCell(null);
  };
  const visibleTools = safeTools.filter(t => selectedIds.includes(t.id));
  const cellKey = (dimId, toolId) => dimId + ":" + toolId;
  const toggleExpand = (dimId, toolId) => {
    const key = cellKey(dimId, toolId);
    setExpandedCell(prev => prev === key ? null : key);
  };
  const renderValue = cell => {
    if (cell.na) {
      return <span className="tc-na">{UI.noSupport}</span>;
    }
    const useMono = cell.mono === true || cell.mono !== false && looksLikePath(cell.value);
    return useMono ? <code className="tc-code">{cell.value}</code> : <span>{cell.value}</span>;
  };
  const css = `
  /* ── 根容器 ── */
  .tc-root {
    --tc-bg:           #FAF8F3;
    --tc-surface:      rgba(0,0,0,0.022);
    --tc-stripe:       rgba(0,0,0,0.028);
    --tc-border:       rgba(0,0,0,0.09);
    --tc-text:         #2b2722;
    --tc-dim:          #6f6a62;
    --tc-faint:        #8a8378;
    --tc-accent:       ${ACCENT_L};
    --tc-accent-bg:    ${REC_BG_L};
    --tc-accent-bdr:   ${REC_BDR_L};
    --tc-expand-bg:    rgba(0,0,0,0.016);
    --tc-code-bg:      rgba(0,0,0,0.055);
    --tc-na-color:     #9a9490;
    --tc-pill-on-bg:   rgba(191,117,81,0.10);
    --tc-pill-on-bdr:  rgba(191,117,81,0.35);
    --tc-pill-on-txt:  #a05c38;
    border: 1px solid var(--tc-border);
    border-radius: 14px;
    background: var(--tc-bg);
    color: var(--tc-text);
    overflow: hidden;
    font-size: 14px;
  }
  .dark .tc-root {
    --tc-bg:           #1b1a18;
    --tc-surface:      rgba(255,255,255,0.03);
    --tc-stripe:       rgba(255,255,255,0.025);
    --tc-border:       rgba(255,255,255,0.08);
    --tc-text:         #e7e3da;
    --tc-dim:          #a8a299;
    --tc-faint:        #706b64;
    --tc-accent:       ${ACCENT_D};
    --tc-accent-bg:    ${REC_BG_D};
    --tc-accent-bdr:   ${REC_BDR_D};
    --tc-expand-bg:    rgba(255,255,255,0.022);
    --tc-code-bg:      rgba(255,255,255,0.08);
    --tc-na-color:     #6e6b65;
    --tc-pill-on-bg:   rgba(207,138,104,0.12);
    --tc-pill-on-bdr:  rgba(207,138,104,0.35);
    --tc-pill-on-txt:  ${ACCENT_D};
  }

  /* ── 精簡篩選列 ── */
  .tc-filter-bar {
    display: flex;
    align-items: center;
    gap: 0;
    padding: 0 14px;
    border-bottom: 1px solid var(--tc-border);
    background: var(--tc-surface);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* 單行、不折行，高度由內容決定（約 36px） */
    flex-wrap: nowrap;
    white-space: nowrap;
    min-height: 36px;
  }
  .tc-filter-bar::-webkit-scrollbar { display: none; }

  /* 分隔竿（All 後面） */
  .tc-filter-sep {
    flex-shrink: 0;
    width: 1px;
    height: 14px;
    background: var(--tc-border);
    margin: 0 10px 0 6px;
    align-self: center;
  }

  /* pill 基底 — 極輕量文字標籤 */
  .tc-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 9px;
    border-radius: 5px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--tc-faint);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: color 0.12s, background 0.12s, border-color 0.12s;
    flex-shrink: 0;
    white-space: nowrap;
    /* 行高對齊 filter-bar */
    margin: 5px 1px;
  }
  .tc-pill:hover {
    color: var(--tc-text);
    background: rgba(0,0,0,0.04);
  }
  .dark .tc-pill:hover {
    background: rgba(255,255,255,0.05);
  }
  /* 選中態：細框 + 淡底 + 文字加深（非按鈕感，保持輕量） */
  .tc-pill-on {
    color: var(--tc-pill-on-txt);
    background: var(--tc-pill-on-bg);
    border-color: var(--tc-pill-on-bdr);
    font-weight: 600;
  }
  /* 全選 pill — 略小一點字型 */
  .tc-pill-all {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 4px 8px;
    color: var(--tc-dim);
  }
  .tc-pill-all.tc-pill-on {
    color: var(--tc-pill-on-txt);
  }
  /* 選中小圓點 */
  .tc-pill-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--tc-accent);
    flex-shrink: 0;
  }

  /* ── 桌面表格 ── */
  .tc-table-wrap {
    overflow: hidden;
  }
  /* Mintlify 的 MDX 渲染器會自動把 <table> 包進 data-table-wrapper：
   * 加 -mx-[var(--page-padding)] 負邊距 + w-[calc(100%+padding*2)] 全寬 + py-[1em]，
   * 讓表格往外溢出，撐破 tc-root 的圓角容器（2026-06-12 線上實證跑版）。
   * 中和它：邊距歸零、寬度收回 100%、把橫向捲動容器設在這層（sticky 左欄靠它）。 */
  .tc-root [data-table-wrapper] {
    margin: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    overflow-x: auto;
    contain: none !important;
  }
  .tc-root [data-table-wrapper] > div {
    padding: 0 !important;
    margin: 0 !important;
  }
  .tc-root [data-table-wrapper]::-webkit-scrollbar { height: 4px; }
  .tc-root [data-table-wrapper]::-webkit-scrollbar-thumb { background: var(--tc-border); border-radius: 2px; }
  .tc-table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 !important;
  }

  /* 表頭 */
  .tc-thead th {
    padding: 9px 15px;
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tc-faint);
    border-bottom: 2px solid var(--tc-border);
    background: var(--tc-surface);
    white-space: nowrap;
  }
  /* 維度欄（sticky 左欄） */
  .tc-thead th:first-child,
  .tc-td-dim {
    position: sticky;
    left: 0;
    z-index: 1;
  }
  .tc-thead th:first-child {
    width: 160px;
    min-width: 130px;
    background: var(--tc-surface);
    border-right: 1px solid var(--tc-border);
    z-index: 2;
  }

  /* 維度標籤欄 */
  .tc-td-dim {
    padding: 13px 15px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--tc-dim);
    vertical-align: middle;
    white-space: nowrap;
    border-bottom: 1px solid var(--tc-border);
    border-right: 1px solid var(--tc-border);
    background: var(--tc-surface);
  }

  /* 斑馬紋：奇數維度列 */
  .tc-row-even .tc-td-dim,
  .tc-row-even .tc-td {
    background-color: var(--tc-stripe);
  }
  .tc-row-even .tc-td-dim {
    background: color-mix(in srgb, var(--tc-surface) 70%, var(--tc-stripe) 30%);
  }

  /* 資料儲存格 */
  .tc-td {
    padding: 0;
    border-bottom: 1px solid var(--tc-border);
    border-left: 1px solid var(--tc-border);
    vertical-align: top;
    min-width: 150px;
  }
  .tc-td-inner {
    display: flex;
    flex-direction: column;
  }

  /* 主值行（可點擊） */
  .tc-cell-btn {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    padding: 13px 15px;
    color: inherit;
    font: inherit;
    font-size: 13px;
    line-height: 1.5;
    cursor: pointer;
    transition: background 0.11s;
    -webkit-tap-highlight-color: transparent;
  }
  .tc-cell-btn:hover {
    background: rgba(0,0,0,0.03);
  }
  .dark .tc-cell-btn:hover {
    background: rgba(255,255,255,0.03);
  }
  .tc-cell-btn-on {
    background: var(--tc-expand-bg);
  }

  /* 推薦標記：左 3px accent 邊框 + 淡底 */
  .tc-td-recommend {
    border-left: 3px solid var(--tc-accent-bdr);
    background: var(--tc-accent-bg);
  }
  .tc-td-recommend .tc-cell-btn:hover {
    background: rgba(191,117,81,0.05);
  }

  /* recommend 角標：超小 badge */
  .tc-rec-badge {
    flex-shrink: 0;
    margin-top: 1px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tc-accent);
    border: 1px solid var(--tc-accent-bdr);
    border-radius: 3px;
    padding: 1px 4px;
    white-space: nowrap;
    opacity: 0.85;
  }

  /* na 樣式 */
  .tc-na {
    font-style: italic;
    color: var(--tc-na-color);
    font-size: 12.5px;
    opacity: 0.7;
  }

  /* 等寬值 */
  .tc-code {
    font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
    font-size: 12px;
    background: var(--tc-code-bg);
    border-radius: 3px;
    padding: 1px 4px;
    word-break: break-all;
  }

  /* 展開詳情列 */
  .tc-detail-row td {
    padding: 0;
    border-bottom: 1px solid var(--tc-border);
  }
  .tc-detail-cell {
    padding: 10px 15px 12px;
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--tc-dim);
    background: var(--tc-expand-bg);
    border-top: 1px dashed var(--tc-border);
    border-left: 1px solid var(--tc-border);
  }
  .tc-detail-cell:first-child {
    border-left: none;
    font-weight: 700;
    color: var(--tc-faint);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    vertical-align: top;
    padding-top: 12px;
    background: var(--tc-surface);
    white-space: nowrap;
    width: 160px;
  }
  .tc-detail-recommend {
    border-left: 3px solid var(--tc-accent-bdr) !important;
    background: var(--tc-accent-bg) !important;
  }

  /* 展開箭頭 */
  .tc-chevron {
    flex-shrink: 0;
    margin-top: 3px;
    opacity: 0.35;
    transition: transform 0.14s, opacity 0.14s;
  }
  .tc-chevron-open {
    transform: rotate(90deg);
    opacity: 0.65;
  }

  /* ── 注腳 ── */
  .tc-notes {
    border-top: 1px solid var(--tc-border);
    padding: 10px 16px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .tc-notes-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--tc-faint);
    margin-bottom: 3px;
  }
  .tc-note-item {
    font-size: 12.5px;
    color: var(--tc-dim);
    line-height: 1.55;
    padding-left: 14px;
    position: relative;
  }
  .tc-note-item::before {
    content: "*";
    position: absolute;
    left: 2px;
    color: var(--tc-faint);
  }

  /* ── 手機模式 ─────────────────────────────────────────── */
  .tc-mobile { display: none; }
  @media (max-width: 700px) {
    .tc-filter-bar { display: none; }
    .tc-table-wrap  { display: none; }
    .tc-mobile      { display: block; }

    .tc-mob-tabs {
      display: flex;
      overflow-x: auto;
      border-bottom: 1px solid var(--tc-border);
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
    }
    .tc-mob-tabs::-webkit-scrollbar { display: none; }
    .tc-mob-tab {
      flex: 1 0 auto;
      padding: 10px 16px;
      background: transparent;
      border: none;
      border-bottom: 2px solid transparent;
      color: var(--tc-dim);
      font: inherit;
      font-size: 13px;
      font-weight: 500;
      cursor: pointer;
      white-space: nowrap;
      transition: color 0.12s, border-color 0.12s;
    }
    .tc-mob-tab-on {
      color: var(--tc-accent);
      border-bottom-color: var(--tc-accent);
      font-weight: 700;
    }
    .tc-mob-cards {
      padding: 12px 0 4px;
    }
    .tc-mob-card {
      border-bottom: 1px solid var(--tc-border);
      padding: 12px 16px;
    }
    .tc-mob-card:last-child { border-bottom: none; }
    .tc-mob-dim {
      font-size: 11px;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--tc-faint);
      margin-bottom: 6px;
    }
    .tc-mob-val {
      font-size: 13.5px;
      line-height: 1.55;
    }
    .tc-mob-rec {
      display: inline-block;
      margin-top: 6px;
      font-size: 9.5px;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--tc-accent);
      border: 1px solid var(--tc-accent-bdr);
      border-radius: 3px;
      padding: 1px 5px;
    }
    .tc-mob-detail {
      margin-top: 7px;
      font-size: 12.5px;
      line-height: 1.65;
      color: var(--tc-dim);
    }
    .tc-notes { padding: 11px 16px 13px; }
  }
  `;
  const renderDesktopTable = () => <div className="tc-table-wrap">
      <table className="tc-table">
        <thead className="tc-thead">
          <tr>
            <th>{UI.dimensionLbl}</th>
            {visibleTools.map(tool => <th key={tool.id}>{tool.label}</th>)}
          </tr>
        </thead>
        <tbody>
          {}
          {safeDimensions.flatMap((dim, dimIdx) => {
    const isAnyExpanded = visibleTools.some(t => expandedCell === cellKey(dim.id, t.id));
    const stripeClass = dimIdx % 2 === 1 ? " tc-row-even" : "";
    const rows = [];
    rows.push(<tr key={dim.id} className={"tc-row" + stripeClass}>
                <td className="tc-td-dim">{dim.label}</td>
                {visibleTools.map(tool => {
      const cell = (dim.cells || ({}))[tool.id] || ({});
      const key = cellKey(dim.id, tool.id);
      const isOpen = expandedCell === key;
      const hasDetail = !!cell.detail;
      const isRec = !!cell.recommend;
      return <td key={tool.id} className={"tc-td" + (isRec ? " tc-td-recommend" : "")}>
                      <div className="tc-td-inner">
                        <button type="button" className={"tc-cell-btn" + (isOpen ? " tc-cell-btn-on" : "")} onClick={hasDetail ? () => toggleExpand(dim.id, tool.id) : undefined} style={hasDetail ? {} : {
        cursor: "default"
      }} aria-expanded={hasDetail ? String(isOpen) : undefined}>
                          <span style={{
        flex: "1 1 0",
        minWidth: 0
      }}>
                            {renderValue(cell)}
                          </span>
                          {isRec && <span className="tc-rec-badge">{UI.recommend}</span>}
                          {hasDetail && <svg className={"tc-chevron" + (isOpen ? " tc-chevron-open" : "")} width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                              <polyline points="9 18 15 12 9 6" />
                            </svg>}
                        </button>
                      </div>
                    </td>;
    })}
              </tr>);
    if (isAnyExpanded) {
      const openToolId = visibleTools.find(t => expandedCell === cellKey(dim.id, t.id))?.id;
      const openCell = openToolId ? (dim.cells || ({}))[openToolId] || ({}) : {};
      if (openCell.detail) {
        const openTool = safeTools.find(t => t.id === openToolId);
        const isRec = !!openCell.recommend;
        rows.push(<tr key={dim.id + "-detail"} className="tc-detail-row">
                    <td className="tc-detail-cell">
                      {openTool ? openTool.label : ""}
                    </td>
                    <td colSpan={visibleTools.length} className={"tc-detail-cell" + (isRec ? " tc-detail-recommend" : "")}>
                      {openCell.detail}
                    </td>
                  </tr>);
      }
    }
    return rows;
  })}
        </tbody>
      </table>
    </div>;
  const renderMobile = () => {
    const activeTool = safeTools.find(t => t.id === mobileTool) || safeTools[0];
    return <div className="tc-mobile">
        <div className="tc-mob-tabs" role="tablist">
          {safeTools.map(tool => <button key={tool.id} type="button" role="tab" aria-selected={tool.id === mobileTool ? "true" : "false"} className={"tc-mob-tab" + (tool.id === mobileTool ? " tc-mob-tab-on" : "")} onClick={() => setMobileTool(tool.id)}>
              {tool.label}
            </button>)}
        </div>

        <div className="tc-mob-cards">
          {safeDimensions.map(dim => {
      const cell = (dim.cells || ({}))[activeTool.id] || ({});
      const isRec = !!cell.recommend;
      return <div key={dim.id} className="tc-mob-card">
                <div className="tc-mob-dim">{dim.label}</div>
                <div className="tc-mob-val">{renderValue(cell)}</div>
                {isRec && <div className="tc-mob-rec">{UI.recommend}</div>}
                {cell.detail && <div className="tc-mob-detail">{cell.detail}</div>}
              </div>;
    })}
        </div>
      </div>;
  };
  return <div className="tc-root">
      <style>{css}</style>

      {}
      <div className="tc-filter-bar">
        <button type="button" className={"tc-pill tc-pill-all" + (isAllSelected ? " tc-pill-on" : "")} onClick={toggleAll} aria-pressed={String(isAllSelected)}>
          {UI.allTools}
        </button>

        {}
        <span className="tc-filter-sep" aria-hidden="true" />

        {safeTools.map(tool => {
    const isOn = selectedIds.includes(tool.id);
    return <button key={tool.id} type="button" className={"tc-pill" + (isOn ? " tc-pill-on" : "")} onClick={() => toggleTool(tool.id)} aria-pressed={String(isOn)}>
              {isOn && <span className="tc-pill-dot" aria-hidden="true" />}
              {tool.label}
            </button>;
  })}
      </div>

      {}
      {visibleTools.length > 0 && renderDesktopTable()}

      {}
      {renderMobile()}

      {}
      {notes.length > 0 && <div className="tc-notes">
          <div className="tc-notes-label">{UI.notes}</div>
          {notes.map((note, i) => <div key={i} className="tc-note-item">{note}</div>)}
        </div>}
    </div>;
};

export const LearnerPrimer = ({items = [], lang = "zh"}) => {
  const t = lang === "en" ? {
    title: "Before this unit, be honest with yourself",
    sub: "If you can't answer these, that gap is exactly what this unit closes."
  } : {
    title: "讀這個單元前，先誠實面對",
    sub: "這幾題答不出來，正是這個單元要替你補的洞。"
  };
  const css = `
  .lp-root{--lp-bg:#FAF7F1;--lp-surface:rgba(191,117,81,0.05);--lp-border:rgba(0,0,0,0.09);--lp-edge:rgba(191,117,81,0.42);--lp-text:#2b2722;--lp-dim:#6f6a62;--lp-accent:#bf7551;border:1px solid var(--lp-border);border-left:3px solid var(--lp-edge);border-radius:13px;background:var(--lp-bg);color:var(--lp-text);overflow:hidden;margin:1.25rem 0;}
  .dark .lp-root{--lp-bg:#1b1a18;--lp-surface:rgba(207,138,104,0.07);--lp-border:rgba(255,255,255,0.08);--lp-edge:rgba(207,138,104,0.5);--lp-text:#e7e3da;--lp-dim:#a8a299;--lp-accent:#cf8a68;}
  .lp-head{display:flex;align-items:center;gap:9px;padding:13px 18px 11px;border-bottom:1px solid var(--lp-border);background:var(--lp-surface);}
  .lp-ic{color:var(--lp-accent);flex-shrink:0;}
  .lp-htx{display:flex;flex-direction:column;gap:1px;min-width:0;}
  .lp-title{font-size:14px;font-weight:650;line-height:1.3;letter-spacing:.01em;}
  .lp-sub{font-size:12px;color:var(--lp-dim);line-height:1.4;}
  .lp-list{list-style:none;margin:0;padding:10px 18px 14px;display:flex;flex-direction:column;gap:0;}
  .lp-item{display:flex;align-items:baseline;gap:11px;padding:7px 0;font-size:14px;line-height:1.6;border-top:1px solid var(--lp-border);}
  .lp-item:first-child{border-top:none;}
  .lp-mark{flex-shrink:0;color:var(--lp-accent);font-size:13px;font-weight:700;line-height:1.55;font-variant-numeric:tabular-nums;opacity:.85;}
  .lp-q{flex:1 1 0;min-width:0;color:var(--lp-text);}
  @media (max-width:620px){.lp-head{padding:12px 14px 10px;}.lp-list{padding:8px 14px 12px;}}
  `;
  return <div className="lp-root">
      <style>{css}</style>
      <div className="lp-head">
        <svg className="lp-ic" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="6" /><circle cx="12" cy="12" r="2" /></svg>
        <span className="lp-htx">
          <span className="lp-title">{t.title}</span>
          <span className="lp-sub">{t.sub}</span>
        </span>
      </div>
      <ul className="lp-list">
        {items.map((q, i) => <li className="lp-item" key={i}>
            <span className="lp-mark">{String(i + 1).padStart(2, "0")}</span>
            <span className="lp-q">{q}</span>
          </li>)}
      </ul>
    </div>;
};

<LearnerPrimer
  lang="en"
  items={[
"CLAUDE.md is context, not enforced configuration",
"You wrote three hundred lines; the model will likely remember three",
"'Cross-task leverage' is not a slogan, it's a filter",
"Put secrets in CLAUDE.md, commit it, and you've already leaked them",
"Whether you write imperatives or descriptions changes compliance by several times",
"Untrusted content enters auto-memory; three weeks later you notice it steering behavior",
"Auto-memory is the agent writing fact notes to its future self",
]}
/>

<Info>
  **What this unit solves**

  `CLAUDE.md` is the standing instruction injected automatically at the start of every session -- the "common sense" you give the agent. Too long and it eats context; too vague and it has no constraining force. This unit unpacks when it is loaded, how the override layers work, the optimal length, and how to modularize it. It also clarifies the division of labor between the instruction-oriented `CLAUDE.md` and the fact-oriented auto-memory, and closes with a cross-tool comparison of project-level instruction file names.
</Info>

## Learning objectives

* [ ] State the four placement locations for `CLAUDE.md` (managed / user / project / local) and their loading priority order.
* [ ] Use the "cross-task leverage" filter to judge which content belongs in `CLAUDE.md` and which does not.
* [ ] Use `@path` import syntax and `.claude/rules/` path scoping to modularize rules and avoid a single monolithic file.
* [ ] Distinguish `CLAUDE.md` (instruction-oriented) from auto-memory (fact-oriented), and identify the risks of memory poisoning and how to handle it.
* [ ] Map the project-level instruction file names of OpenAI Codex, Google Antigravity, GitHub Copilot, and Cursor to their Claude Code equivalents.

***

## 1. What `CLAUDE.md` is and when it is loaded

`CLAUDE.md` is a plain-text Markdown file stored on disk. Claude Code reads it at the start of every session and injects it into the conversation context as a user message. Once loaded, it occupies token budget in the context window alongside everything you say.

Two key facts to internalize first:

* It is **context**, not enforced configuration. Claude will "try to comply," but there is no hard guarantee when conflicts arise or rules are missed. For hard guarantees, see Section 8 on the difference between hooks and context.
* It is a **standing message injected in full every session**, unlike a Skill which is loaded on demand (see [04-4 Skills](/en/code-agent/customization/skills)). Every line you write costs tokens every time.

<Tip>
  **`/init` is the fastest starting point**

  Run `/init` in a new project directory and Claude Code will automatically scan your codebase and generate a starter `CLAUDE.md` covering build commands, test workflows, and project conventions. It reads what can be mechanically inferred; you then add what it cannot infer but needs to know every session.
</Tip>

## 2. Placement locations and override layers

Claude Code searches for and loads `CLAUDE.md` in the following order at startup (as of 2026-06, per the official memory documentation \[1]):

| Scope          | Location                                                                                                                                           | Purpose                                                                    | Who sees it                              |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------- |
| Managed policy | macOS `/Library/Application Support/ClaudeCode/CLAUDE.md`, Linux/WSL `/etc/claude-code/CLAUDE.md`, Windows `C:\Program Files\ClaudeCode\CLAUDE.md` | Organization-wide mandatory rules (security, coding standards, compliance) | All machines in the organization         |
| User level     | `~/.claude/CLAUDE.md`                                                                                                                              | Personal cross-project preferences (indentation, tool shortcuts, language) | Only you                                 |
| Project level  | `./CLAUDE.md` or `./.claude/CLAUDE.md`                                                                                                             | Team-shared project conventions                                            | Shared with the team via version control |
| Local override | `./CLAUDE.local.md`                                                                                                                                | Personal private settings for this project (sandbox URLs, local test data) | Only you; add to `.gitignore`            |

<Warning>
  **Loading order is not "overriding"**

  Multiple files are **concatenated** into context, not the later one overwriting the earlier. They are joined in order from root toward the working directory, with local files read last. When `CLAUDE.md` and `CLAUDE.local.md` are in the same layer, the local file is appended after. This means a `CLAUDE.md` placed in a parent directory will be read by any session started in any of its subdirectories.
</Warning>

The managed policy is published by the organization and cannot be disabled by individuals. Personal and project-level `CLAUDE.md` files can use `claudeMdExcludes` to exclude specific files (settable at any configuration layer; arrays are merged across layers). This is useful in large monorepos for preventing another team's `CLAUDE.md` from polluting yours. The managed policy `CLAUDE.md` cannot be excluded \[1].

## 3. What to write and what not to: the cross-task leverage principle

The filter comes down to one sentence: **if a rule will still be useful next session, write it in; if it is only useful once, do not.** Applying this standard quickly eliminates 80% of candidates.

Content that belongs in `CLAUDE.md`:

* **Role and language**: second-person voice, response language, terminology glossary.
* **Coding style**: indentation, naming, quote style, module-splitting conventions.
* **Build and test commands**: `make test`, `uv run pytest`, `pnpm lint`, and the like.
* **Project structure and boundaries**: "API handlers live in `src/api/handlers/`", "do not touch `dist/`".
* **Prohibitions**: "do not modify existing files in `migrations/`", "never commit any `.env`".
* **Common workflows**: "after fixing a bug, run `make lint` before committing".

Content that does not belong:

* One-off task details ("merge PR #1234 into main for me").
* Frequently changing version numbers and package lists (these go stale and belong in lockfiles).
* Secrets (API keys, passwords, tokens). `CLAUDE.md` goes into version control; secrets belong in `.env` guarded by `.gitignore`.
* Verbose background (more than a page of project history or design philosophy). Background should be passed in conversation context, not left standing.
* Content that belongs on another axis: multi-step procedures, cross-file refactor SOPs, release workflows -- split these into Skills (see [04-4 Skills](/en/code-agent/customization/skills)).

<Note>
  **Write imperatives, not descriptions**

  `CLAUDE.md` is "what to comply with," not a project introduction. For the same content, the imperative version is several times more effective than the descriptive version.

  Do not write: "Our tests use the pytest framework, running on Python 3.11+, primarily using fixtures and parametrize..." (description)

  Write instead: "Run tests with `uv run pytest`; for a single test file use `uv run pytest path/to/test_x.py -k name`" (imperative)

  Imperatives make it much easier for the model to extract "what to do."
</Note>

## 4. Length and token budget

Anthropic's official guidance on `CLAUDE.md` length is **200 lines or fewer per file** \[1]. This is not a hard limit, but there are two reasons for it:

1. **Adherence degrades.** The longer the file, the lower the fraction of rules the model remembers and follows across multiple turns. Shorter is more consistent.
2. **Every session burns tokens.** Once `CLAUDE.md` is loaded it is not removed from context (unless you manually `/compact` and re-trigger loading). The longer it is, the same cost is paid on every interaction.

If a rule is only needed **in a specific subdirectory or file extension**, move it to `.claude/rules/<topic>.md` and constrain it with `paths` frontmatter (see [04-2 rules](/en/code-agent/customization/rules)). That way it is not fully loaded in every session -- only when Claude touches matching files.

<Note>
  **Real cost: the difference between 200 and 800 lines**

  Assume `CLAUDE.md` is about 200 lines averaging 25 tokens per line. A single session starts with 5,000 tokens of static overhead. The same content inflated to 800 lines costs 20,000 tokens. In a 200k context window, the 800-line version permanently consumes roughly 7.5% more of the available conversation space. With Claude Opus 4.5 input costs, the 800-line version can cost hundreds of dollars more per year -- before counting the correction cost from degraded adherence.
</Note>

### Structured segmentation

Group sections under explicit Markdown headings and avoid large blocks of prose. The model scans structure; concentrating related rules under a single `##` heading is more stable than scattering them across three paragraphs.

<Note>
  **Block comments are stripped**

  The official implementation strips `<!-- ... -->` HTML block comments before loading `CLAUDE.md` into context \[1]. This means comments intended for human maintainers (e.g., "this section came from the 2026-04 linting discussion") do not consume tokens. Comments inside code blocks are not stripped. Comments remain visible when you open `CLAUDE.md` with the Read tool; only the copy injected into the model is stripped.
</Note>

## 5. Modularization: avoiding the monolithic file

Two orthogonal tools let you split the file.

### 5.1 Importing with `@path`

Inside `CLAUDE.md` you can import other files using `@path/to/import` syntax \[1]:

```text theme={null}
# CLAUDE.md
See @README for project overview and @package.json for available npm commands.

# Coding standards
- Python style: @docs/python-style.md
- API design: @docs/api-conventions.md
```

Rules:

* Relative paths are resolved against the file that contains the `@`, not the current working directory.
* Imports can be recursive up to 4 levels deep.
* Imported files are **also loaded in full at session startup**, so `@` imports are for organizational structure, not for saving tokens. To save tokens, use the path-scoped mechanism in `.claude/rules/`.
* The first time an external import is used, Claude Code shows a trust confirmation dialog. Clicking "reject" disables imports for that project \[1].

<Tip>
  **Sharing personal preferences across worktrees**

  If you use multiple git worktrees, put cross-worktree personal preferences in `~/.claude/my-project-instructions.md` and reference it with `@~/.claude/my-project-instructions.md` in each worktree's `CLAUDE.md`, eliminating duplicate edits.
</Tip>

### 5.2 Splitting into `.claude/rules/`

When a rule is only needed **for specific file extensions or subdirectories**, move the entire rule to `.claude/rules/<topic>.md` and use `paths` frontmatter to limit its reach (see [04-2 rules](/en/code-agent/customization/rules)). Files in `.claude/rules/` **without `paths`** are equivalent to `CLAUDE.md` -- they are loaded in full at session startup. Once `paths` is specified, they are only loaded when Claude touches files matching the glob.

<Tabs>
  <Tab title="Before splitting (monolithic, 320 lines)">
    ```markdown theme={null}
    # Role and language (20 lines)
    # Build and test (30 lines)
    # Python coding style (120 lines)
    # API design standards (80 lines)
    # Frontend React standards (70 lines)
    ```

    All 320 lines are injected in full at every session startup.
  </Tab>

  <Tab title="After splitting (load only what is needed)">
    ```text theme={null}
    CLAUDE.md            # 50 lines: role, language, build, test, global prohibitions
    .claude/rules/
      python-style.md    # 120 lines, paths: ["**/*.py"]
      api-design.md      # 80 lines, paths: ["src/api/**"]
      react-style.md     # 70 lines, paths: ["src/components/**/*.{ts,tsx}"]
    ```

    Each session startup costs only 50 lines. Touching a Python file adds 120 lines; touching an API handler adds 80 lines. "Load only when relevant" is how you spend tokens where they matter.
  </Tab>
</Tabs>

## 6. Auto-memory: fact-oriented memory

`CLAUDE.md` is the **instructions** you write for Claude. Auto-memory is the **fact notes** Claude writes for its future self \[1]. The two work together:

|            | `CLAUDE.md`                                    | Auto-memory                                                                                                                   |
| ---------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Written by | You                                            | Claude itself                                                                                                                 |
| Content    | Instructions, rules, conventions               | Observed facts: build commands, debugging insights, discovered preferences                                                    |
| Scope      | Project, user, organization                    | Per git repo (shared across all worktrees and subdirectories of the same repo; keyed to project root when outside a git repo) |
| Loading    | Full load every session                        | Loads `MEMORY.md` up to the first 200 lines or 25KB (whichever comes first); topic files loaded on demand                     |
| Suited for | Coding standards, workflows, project structure | Build commands, debugging observations, preferences Claude learned from conversation                                          |

Storage location: `~/.claude/projects/<project>/memory/`, containing a `MEMORY.md` index file and multiple topic files (`debugging.md`, `api-conventions.md`, etc.) \[1]. This is **machine-local** -- it does not sync across machines or to the cloud, but it is shared across worktrees within the same repo.

Requirements: Claude Code v2.1.59 or later \[1]. On by default; disable with `/memory` or by setting `autoMemoryEnabled: false` in `settings.json`, or with the environment variable `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1`. To change the default storage location, use `autoMemoryDirectory` in `settings.json` (accepts an absolute path or `~/` prefix; setting this at the project or local layer requires passing the workspace trust dialog first) \[1].

<Warning>
  **Auto-memory cuts both ways**

  Claude decides whether to write based on "will this be useful in a future conversation?" What it writes may not be what you want (for example, recording an experimental approach you mentioned in passing as a persistent preference). The `/memory` command lets you browse, open, edit, and delete memory files. Treat it like your own notes: review it periodically.
</Warning>

## 7. Memory poisoning: the supply-chain risk of auto-memory

When external content enters the agent and is written into auto-memory, it influences behavior when loaded in the next session. This is **memory poisoning**. For the concrete attack surface see [03-3 Security, Privacy, and Supply-Chain Risk](/en/code-agent/judgment/security-privacy-supply-chain). The relevant mitigations for this unit are:

* **After workflows that process untrusted content**, clear or rotate the contents of `~/.claude/projects/<project>/memory/`.
* **Review auto-memory periodically**: run `/memory` to open the folder and at minimum scan `MEMORY.md` and each topic file.
* **Secrets do not belong in auto-memory**: Claude may write API keys or tokens you pasted into a conversation. `MEMORY.md` is a plain-text local file with no encryption; it travels with your backup or sync.

## 8. Division of labor with hooks: `CLAUDE.md` says "please comply"; hooks enforce

`CLAUDE.md` is context that the model references while generating responses. For prohibitions like "do not commit `.env`", the model may miss this in a long-chain task. **Hooks provide the hard guarantee** (see [04-6 Hooks](/en/code-agent/customization/hooks)):

* `CLAUDE.md`: "do not commit `.env` files" -- the model will usually remember, but occasionally misses.
* Hook (PreToolUse on Bash): when `Bash(git commit *)` is triggered, a shell check for `.env` in staged files exits with code 2 and blocks -- every time, without exception.

The criterion: use `CLAUDE.md` when you need the model to "remember"; use a hook when you need it "blocked regardless."

## 9. Tool comparison: project-level instruction files across tools

`AGENTS.md` has become the cross-tool shared project rules file natively supported by multiple tools. It is maintained by the Agentic AI Foundation under the Linux Foundation and as of 2026-06 had been adopted by 60,000+ open-source projects (adoption figures and governance claims sourced from \[4], not Anthropic official documentation). Claude Code reads `CLAUDE.md` natively, but `@AGENTS.md` can be imported to bring it in \[1].

<Note>
  **Official position: Claude reads `CLAUDE.md`, not `AGENTS.md`**

  The Anthropic official memory documentation states: "Claude Code reads `CLAUDE.md`, not `AGENTS.md`. If your repository already uses `AGENTS.md` for other coding agents, create a `CLAUDE.md` that imports it so both tools read the same instructions without duplication." Source: Claude Code memory documentation, AGENTS.md section (official) (as of 2026-06) \[1].

  The minimal approach from the official docs: first line of `CLAUDE.md` is `@AGENTS.md`, followed by Claude-specific instructions. If no Claude-specific content is needed, `ln -s AGENTS.md CLAUDE.md` also works. Creating symlinks on Windows requires administrator privileges or Developer Mode, so Anthropic recommends using `@AGENTS.md` import on Windows instead.
</Note>

<ToolCompare
  lang="en"
  tools={[
{ id: "claude", label: "Claude Code" },
{ id: "codex",  label: "OpenAI Codex" },
{ id: "gemini", label: "Google Gemini CLI" },
{ id: "copilot",label: "GitHub Copilot" },
{ id: "cursor", label: "Cursor" },
]}
  dimensions={[
{
  id: "user-instr",
  label: "User-level instructions",
  cells: {
    claude:  { value: "~/.claude/CLAUDE.md",                       recommend: true },
    codex:   { value: "~/.codex/AGENTS.md" },
    gemini:  { value: "~/.gemini/GEMINI.md, ~/.gemini/AGENTS.md" },
    copilot: { value: "~/.copilot/copilot-instructions.md" },
    cursor:  { value: "User Rules (GUI)", detail: "Cursor user-level rules are configured via the GUI; there is no equivalent settings file path." },
  },
},
{
  id: "proj-instr",
  label: "Project-level instructions",
  cells: {
    claude:  { value: "./CLAUDE.md, .claude/CLAUDE.md",            recommend: true },
    codex:   { value: "./AGENTS.md" },
    gemini:  { value: "./GEMINI.md, ./AGENTS.md, .agent/rules/" },
    copilot: { value: ".github/copilot-instructions.md, .github/instructions/*.instructions.md, AGENTS.md" },
    cursor:  { value: ".cursor/rules/*.mdc", detail: "Extension must be .mdc; .md is ignored. Frontmatter fields: description / globs / alwaysApply." },
  },
},
{
  id: "local-override",
  label: "Local override",
  cells: {
    claude:  { value: "./CLAUDE.local.md",                         recommend: true, detail: "Add to .gitignore; the standard location for personal machine-specific settings." },
    codex:   { value: "CLI flags", detail: "Codex overrides settings via CLI options; no equivalent local file layer." },
    gemini:  { value: "Workspace-based" },
    copilot: { value: "Personal layer primary" },
    cursor:  { value: "No equivalent local layer" },
  },
},
{
  id: "modular",
  label: "Modular splitting",
  cells: {
    claude:  { value: ".claude/rules/*.md (path-scoped)",           recommend: true, detail: "paths frontmatter restricts loading to matching globs -- the core token-saving mechanism." },
    codex:   { value: "AGENTS.md, AGENTS.override.md" },
    gemini:  { value: "Multiple .agent/rules/ files + GEMINI.md" },
    copilot: { value: "Multiple .instructions.md + applyTo glob" },
    cursor:  { value: "Multiple .mdc files", detail: "alwaysApply: true loads unconditionally; globs triggers auto-load on match; description only lets the model decide by relevance; nothing set requires manual @-mention." },
  },
},
{
  id: "cross-tool",
  label: "Cross-tool shared layer",
  cells: {
    claude:  { value: "Reads CLAUDE.md; @AGENTS.md import available", detail: "Official recommendation: first line of CLAUDE.md is @AGENTS.md, followed by Claude-specific instructions." },
    codex:   { value: "AGENTS.md native" },
    gemini:  { value: "AGENTS.md native" },
    copilot: { value: "AGENTS.md native" },
    cursor:  { value: "AGENTS.md native" },
  },
},
{
  id: "auto-memory",
  label: "Auto-memory",
  cells: {
    claude:  { value: "~/.claude/projects/<repo>/memory/ (v2.1.59+)", recommend: true, detail: "Fact notes written by Claude itself, shared by git repo. The /memory command lets you browse, edit, and delete entries." },
    codex:   { value: "AGENTS.md as standing instruction; no dedicated fact memory" },
    gemini:  { value: "Memory (account-side)", detail: "Google Gemini memory is stored on the account, not mapped to a local git repo." },
    copilot: { na: true },
    cursor:  { na: true },
  },
},
{
  id: "enforcement",
  label: "Hard enforcement guarantee",
  cells: {
    claude:  { value: "Hook (PreToolUse / PostToolUse)",            recommend: true, detail: "Hooks are a hard guarantee: exit code 2 blocks the tool call unconditionally, without relying on the model remembering the rule." },
    codex:   { value: "Codex hooks" },
    gemini:  { value: "Antigravity workflow" },
    copilot: { value: "Copilot hooks (preview)" },
    cursor:  { value: "No equivalent mechanism" },
  },
},
]}
  notes={[
"Claude Code reads CLAUDE.md, not AGENTS.md, unless imported with @AGENTS.md.",
"Google Gemini CLI has no official `gemini mcp add` CLI; editing settings.json directly is recommended (as of 2026-06).",
"Cursor is a third-party IDE (Anysphere); this Playbook includes only a brief column for it.",
]}
/>

<Note>
  **Naming clarification**

  The primary column uses current official naming. Claude Code's standing instruction file is `CLAUDE.md` (not `AGENTS.md`); if a project already has `AGENTS.md`, use `@AGENTS.md` import to have Claude read it too. Google Antigravity reads both `GEMINI.md` and `AGENTS.md`; priority ordering is inconsistent across sources -- see [02-6 Other Tools Comparison](/en/code-agent/configuration/other-tools-comparison) for details. Cursor is a third-party IDE (Anysphere); this Playbook only includes a brief column for it.
</Note>

## 10. Hands-on exercise

<Steps>
  <Step title="Prune">
    Apply the "cross-task leverage" filter to every rule in your current `CLAUDE.md` (if you have one). Delete anything only useful for a one-off task. Compare line counts before and after.
  </Step>

  <Step title="Split">
    If your Python or frontend coding style exceeds 30 lines, extract it to `.claude/rules/<lang>-style.md` and add a `paths` frontmatter constraint.
  </Step>

  <Step title="Local layer">
    Move any settings that are only needed on your local machine (sandbox URLs, test data locations) to `CLAUDE.local.md` and add it to `.gitignore`.
  </Step>

  <Step title="Verify">
    Start `claude` in the same working directory and run `/memory` to confirm all files that should be loaded appear in the list.
  </Step>

  <Step title="Trust dialog">
    The first time you use `@path` to import an external file, a trust confirmation will appear. Decide your strategy in advance: full project trust, or per-file approval.
  </Step>
</Steps>

## 11. Common pitfalls

<Warning>
  **Anti-pattern list**

  * **Copying someone else's `CLAUDE.md`**: their conventions reflect their workflow. Copying blindly introduces constraints you do not need and potentially security risks (see [03-3 Security, Privacy, and Supply-Chain Risk](/en/code-agent/judgment/security-privacy-supply-chain)). Start from the skeleton and rewrite for your own workflow.
  * **Growing `CLAUDE.md` indefinitely until layers contradict each other**: the model **picks one** when rules conflict, and you may not know which. Review layered files regularly and delete stale rules.
  * **Writing "must enforce" rules as imperatives in `CLAUDE.md`**: rules that require hook enforcement written only in `CLAUDE.md` will occasionally be missed. For deterministic guarantees, see [04-6 Hooks](/en/code-agent/customization/hooks).
  * **Putting `.env` content in `CLAUDE.md`**: it goes into version control, which means the secrets are no longer secret. Secrets belong in `.env` guarded by `.gitignore`.
  * **Copying a single file name across all tools**: Claude does not read `AGENTS.md` (unless you `@` import it), and GitHub Copilot does not read `CLAUDE.md`. For cross-tool setups, use `AGENTS.md` as the shared foundation and attach tool-specific settings separately.
</Warning>

## Self-check

<Check>
  **The bar for passing this unit**

  1. Can you state in under a minute the four placement locations for `CLAUDE.md`, their loading order, and which layer can be disabled and which cannot?
  2. For every rule in your own `CLAUDE.md`, can you state "what breaks if this is deleted"? Keep the ones you can answer; delete the ones you cannot.
  3. Can you articulate the criterion for "does this go in `CLAUDE.md`, `.claude/rules/`, a Skill, or a Hook"?
  4. Do you know where auto-memory is stored, how to inspect it, and how to clear it?
</Check>

## Sources and further reading

Factual claims are grounded in official documentation; fast-changing items are annotated as of 2026-05.

<div className="references">
  * \[1] Anthropic, "How Claude remembers your project," code.claude.com, 2026. \[Online]. Available: [https://code.claude.com/docs/en/memory](https://code.claude.com/docs/en/memory) (as of 2026-06)

  * \[2] Anthropic, "Extend Claude with skills," code.claude.com, 2026. \[Online]. Available: [https://code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills) (as of 2026-06; includes Skill and instruction mechanism integration)

  * \[3] Cursor, "Rules," cursor.com, 2026. \[Online]. Available: [https://cursor.com/docs/context/rules](https://cursor.com/docs/context/rules) (as of 2026-06; `.mdc` and `globs` frontmatter mechanism)

  * \[4] Agentic AI Foundation (Linux Foundation), "AGENTS.md, a simple, open format for guiding coding agents," 2026. \[Online]. Available: [https://agents.md/](https://agents.md/) (as of 2026-06; 60,000+ open-source projects; full list of supporting tools on that page)
</div>

* Configuration layer model: [02-1 Configuration Layer Model](/en/code-agent/configuration/config-layer-model).
* Hook enforcement: [04-6 Hooks](/en/code-agent/customization/hooks).
* Path-scoped rules mechanism: [04-2 rules](/en/code-agent/customization/rules).
* Skills (on-demand procedures): [04-4 Skills](/en/code-agent/customization/skills).
* Supply-chain risks of auto-memory: [03-3 Security, Privacy, and Supply-Chain Risk](/en/code-agent/judgment/security-privacy-supply-chain).
