Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 45 additions & 43 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,16 @@ bundle exec jekyll build # 결과물은 _site/ 에 생성
```

> **왜 `github-pages` gem이 아니라 순수 `jekyll`인가요?**
> 이 사이트는 `_plugins/`에 직접 만든 Ruby 플러그인(읽기 시간, 이미지 lazy-load, 글 설명문 생성)을 씁니다.
> `github-pages` gem은 보안 샌드박스 때문에 커스텀 플러그인을 막으므로,
> 로컬과 CI 모두 Jekyll을 직접 실행합니다.
> 이 사이트는 `_plugins/`에 직접 만든 Ruby 플러그인을 씁니다. `github-pages` gem은 보안
> 샌드박스 때문에 커스텀 플러그인을 막으므로, 로컬과 CI 모두 Jekyll을 직접 실행합니다.

---

## 저장소 구조

```
_posts/ 글 — YYYY-MM-DD-slug.md (한국어 기본, 영어 번역본은 -en.md)
_layouts/ 페이지 템플릿: default → post / page / archive
_layouts/ 페이지 템플릿: default → post / page
_includes/ 재사용 조각: head, header, footer, nav_links,
page_divider, category-posts, language_switcher,
related_posts
Expand All @@ -76,7 +75,7 @@ _sass/ 스타일: _layout, _post, _tags, _syntax(Rouge 코드 테마
_plugins/ reading_time.rb (한·영 읽기 시간 계산)
lazy_images.rb (<img>에 loading="lazy" 추가)
post_description.rb (글의 page.description 채우기)
related_posts.rb (글의 page.related 채우기)
related_posts.rb (page.related, 그리고 이전/다음 글 링크)
scrollable_tables.rb (넓은 표를 스크롤 컨테이너로 감싸기)
css/ main.scss(Sass 진입점) · search.css(검색 페이지 전용)
js/ main.js(테마 토글·코드 복사·목차·메뉴·이미지 확대 등)
Expand Down Expand Up @@ -138,20 +137,29 @@ RSS `<summary>`에 실리는 문장입니다. 생략하면 `_plugins/post_descri
카테고리는 **두 단계**입니다.

- `categories[0]` — **유형**: `Paper Reviews`, `Paper Summaries`, `Tech Guides`,
`Insights` 중 하나. 글이 어느 섹션 페이지에 들어갈지를 정합니다. 현재 글이 있는 유형은
`Paper Reviews`와 `Insights`뿐이라 내비에도 이 둘만 있습니다 — `paper-summaries.md`와
`tech-guides.md`는 `main_nav` 없이 `sitemap: false` 상태이고, 첫 글이 들어오면 어떤 두
값을 되살리면 되는지가 각 파일 프런트매터에 적혀 있습니다.
`Insights` 중 하나. 글이 어느 내비 탭에 들어갈지를 정합니다. 아직 글이 없는 유형도
**탭을 유지하고** 빈 상태 문구를 띄웁니다 — 탭이 없으면 채우는 중인 섹션이 아니라
없어진 섹션으로 읽히기 때문입니다.
- `categories[1]` — **주제**: `Language-Models`, `Multimodal-Learning`,
`Finetuning`, `Retrieval-Augmented-Generation`, `Agentic-AI` 등. 필요하면 자유롭게 추가합니다.

Jekyll은 이 둘과 날짜를 합쳐 출력 경로를 만듭니다.

```
categories: ["Paper Reviews", "Language-Models"] + date: 2025-01-23
_site/paper reviews/language-models/2025/01/23/<slug>.html
```

그래서 **이미 게시된 글의 카테고리나 날짜를 바꾸면 URL이 바뀝니다.** 외부에서 걸린 링크와
검색 결과가 깨지므로, 한 번 정하면 그대로 둡니다.

### 태그: 세부 태그 위에 주제 태그를 하나

태그는 자유 형식·하이픈 연결이고, 대부분 논문 하나의 기여를 서술합니다
(`Fine-Grained-Expert-Segmentation`). 색인으로는 좋지만 글을 **잇지는** 못합니다 — 태그
264개 중 220개가 단 한 편에만 붙어 있었고, `_plugins/related_posts.rb`는 **공유** 태그를
요구하므로 11편이 관련 글을 하나도 얻지 못했습니다. 서로 남남이던 그래프 RAG 논문 네 편이
거기 있었습니다.
태그는 자유 형식·하이픈 연결입니다. 논문 하나의 기여를 그대로 옮긴 태그
(`Fine-Grained-Expert-Segmentation`)는 그 논문에만 붙을 수 있습니다. 색인으로는 정확하지만
글을 **잇지는** 못하고, `_plugins/related_posts.rb`가 **공유** 태그를 요구하므로 그렇게만
달린 글은 "Related reading"이 아예 붙지 않은 채 배포됩니다.

그래서 글마다 아래 통제된 주제 태그를 최소 하나 답니다.

Expand All @@ -162,17 +170,11 @@ Retrieval-Augmented-Generation
```

기존 세부 태그는 **그대로 남깁니다.** 주제 태그가 담지 못하는 내용을 담고 있고, 지우면 이미
살아 있는 `/tags/` 앵커가 움직입니다. 새 주제 태그를 만들기 전에 위 목록이나 이미 두 편
이상이 쓰는 태그로 덮이는지 먼저 확인하세요. `Agentic-Architecture`·`Agentic-Patterns`·
`Agentic-Infrastructure`가 한 주제의 세 이름이었던 것이 그 묶음에 링크가 없던 이유입니다.

Jekyll은 이 둘과 날짜를 합쳐 출력 경로를 만듭니다.
살아 있는 `/tags/` 앵커가 움직입니다. **주제 태그는 얹는 것이지 바꿔 다는 게 아닙니다.**

```
categories: ["Paper Reviews", "Language-Models"] + date: 2025-01-23
_site/paper reviews/language-models/2025/01/23/<slug>.html
```
새 주제 태그를 만들기 전에 위 목록에 이미 덮이는 게 없는지 확인하세요. 한 개념을 세 이름으로
부르면(`Agentic-Architecture`·`Agentic-Patterns`·`Agentic-Infrastructure`) 글마다 아무도
공유하지 않는 태그를 하나씩 들고 있게 되고, 그건 주제 태그가 없는 것과 같습니다.

### 수식은 반드시 `$$…$$`로

Expand All @@ -186,39 +188,39 @@ kramdown이 내용을 그대로 보존해 `\(…\)`로 내보내므로 안전합

### 푸시 전에 확인하세요

CI가 돌리는 네 게이트를 같은 순서로 미리 돌립니다. `_site/`가 아니라 임시 경로로 빌드하는
이유는 아래 주의에 있습니다.

```bash
ruby test/run_all.rb # 플러그인 로직이 여전히 맞나?
bundle exec jekyll build # 빌드가 깨끗한가?
bundle exec htmlproofer ./_site --disable-external # 깨진 링크·이미지는 없나?
script/validate-site.sh # 사이트맵·피드·메타데이터·헤딩
ruby test/run_all.rb # 플러그인 로직이 여전히 맞나?
bundle exec jekyll build --strict-front-matter \
--destination /tmp/site-verify # 빌드가 깨끗한가?
bundle exec htmlproofer /tmp/site-verify --disable-external \
--allow-hash-href --no-enforce-https # 깨진 링크·이미지·앵커는 없나?
script/validate-site.sh /tmp/site-verify # 사이트맵·피드·메타데이터·헤딩
```

CI도 같은 세 검사를 돌립니다. 로컬에서 미리 잡으면 배포 실패를 막을 수 있습니다.

`test/`는 `_plugins/`를 검사합니다 — 설명문 추출, 읽기 시간 계산, 이미지 lazy-load
치환. `bundle exec`가 아니라 plain `ruby`인 이유는, 플러그인이 Jekyll·Liquid 등록을
`defined?`로 감싸 로직만 단독 로드되게 해 두었고 minitest는 Ruby에 기본 포함이기
때문입니다. **`_plugins/`를 건드리면 사이트의 모든 페이지가 바뀝니다.** 동작을 바꾸기
전에 테스트 케이스를 먼저 추가하세요.

> **검사 결과가 말이 안 되면 먼저 떠 있는 `jekyll serve`를 찾으세요.** 파일을 감시하며
> `_site/`를 계속 덮어쓰고, `site.url`을 `http://localhost:4000`으로 바꾸며(사이트맵 URL이
> 전부 틀리게 보입니다), 시작할 때 읽은 `_config.yml`을 계속 들고 있어 그 뒤에 추가한
> `exclude`가 적용되지 않습니다. 종료하거나, 다른 경로로 빌드해서 검사하세요.
> `exclude`가 적용되지 않습니다. 다른 경로로 빌드하면 세 문제를 한꺼번에 비켜 갑니다.
>
> ```bash
> ps aux | grep '[j]ekyll serve'
> bundle exec jekyll build --destination /tmp/site-verify
> script/validate-site.sh /tmp/site-verify
> ```

`test/`는 `_plugins/`의 순수 로직을 플러그인당 한 파일씩 단위 테스트합니다. `bundle exec`가
아니라 plain `ruby`인 이유는, 각 플러그인이 Jekyll·Liquid 등록을 `defined?`로 감싸 로직만
단독 로드되게 해 두었고 minitest는 Ruby에 기본 포함이기 때문입니다. **`_plugins/`를 건드리면
사이트의 모든 페이지가 바뀝니다.** 동작을 바꾸기 전에 테스트 케이스를 먼저 추가하세요.

---

## 배포

`.github/workflows/jekyll.yml`은 `main` 푸시뿐 아니라 **`main`으로 향하는 PR에서도**
돕니다. 그래서 아래 게이트가 잘못된 머지를 보고만 하지 않고 막습니다. 1~4단계는 양쪽
모두에서, 5단계는 PR에서 건너뜁니다.
돕니다. 그래서 아래 게이트가 잘못된 머지를 사후에 보고하는 데 그치지 않고 막습니다.
1~4단계는 두 경우 모두, 5단계는 PR에서 건너뜁니다. 순서대로:

1. **`ruby test/run_all.rb`**로 `_plugins/` 단위 테스트를 돌리고
2. `JEKYLL_ENV=production`으로 사이트를 빌드하고
Expand All @@ -230,8 +232,8 @@ CI도 같은 세 검사를 돌립니다. 로컬에서 미리 잡으면 배포
중복되지 않는지, 저작 원본이 배포되지 않았는지를 검사한 뒤
5. GitHub Pages에 배포합니다.

워크플로우가 실패한다면 대개 3·4단계입니다. Actions 로그에 어떤 링크·이미지·페이지가
문제인지 그대로 나옵니다. 수동 배포 단계는 없습니다.
실패하면 대개 3·4단계입니다. Actions 로그에 어떤 링크·이미지·페이지가 문제인지 그대로
나옵니다. 수동 배포 단계는 없습니다.

> **⚠ `google*.html` / `naver*.html`을 `_config.yml`의 `exclude`에 넣지 마세요.**
> Search Console·네이버 소유권 인증 토큰이라 사이트 루트에 그대로 올라가야 합니다.
Expand Down
99 changes: 51 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,16 @@ bundle exec jekyll build
```

> **Why plain `jekyll` and not `github-pages`?** This site uses custom Ruby
> plugins in `_plugins/` (read time, lazy images, post descriptions), which the
> sandboxed `github-pages` gem disallows. So both local builds and CI run Jekyll
> directly.
> plugins in `_plugins/`, which the sandboxed `github-pages` gem disallows. So
> both local builds and CI run Jekyll directly.

---

## Project structure

```
_posts/ Posts — YYYY-MM-DD-slug.md (Korean; English twin is -en.md)
_layouts/ Page templates: default → post / page / archive
_layouts/ Page templates: default → post / page
_includes/ Reusable fragments: head, header, footer, nav_links,
page_divider, category-posts, language_switcher,
related_posts
Expand All @@ -78,7 +77,7 @@ _sass/ Styles: _layout, _post, _tags, _syntax (Rouge code theme),
_plugins/ reading_time.rb (KO/EN-aware read time)
lazy_images.rb (adds loading="lazy" to <img>)
post_description.rb (fills page.description for posts)
related_posts.rb (fills page.related for posts)
related_posts.rb (page.related, and the prev/next links)
scrollable_tables.rb (wraps wide tables so they scroll)
css/ main.scss (Sass entry point) · search.css (search page only)
js/ main.js (theme toggle, code-copy, TOC, menu, image zoom…)
Expand Down Expand Up @@ -142,23 +141,31 @@ share one.
Categories are **two levels**:

- `categories[0]` — the **type**: `Paper Reviews`, `Paper Summaries`,
`Tech Guides`, or `Insights`. This decides which section page the post appears
on. Only `Paper Reviews` and `Insights` have posts today, so only those two are
in the nav — `paper-summaries.md` and `tech-guides.md` sit at `sitemap: false`
with no `main_nav`, and their front matter says which two keys to restore when
the first post lands in either.
`Tech Guides`, or `Insights`. This decides which nav tab the post appears under.
A type with no posts yet keeps its tab and renders an empty-state line: a
missing tab reads as a section that was removed, not one still filling up.
- `categories[1]` — the **topic**: `Language-Models`, `Multimodal-Learning`,
`Finetuning`, `Retrieval-Augmented-Generation`, `Agentic-AI`, … (add new ones
freely).

Jekyll combines the two with the date to build the output path:

```
categories: ["Paper Reviews", "Language-Models"] + date: 2025-01-23
_site/paper reviews/language-models/2025/01/23/<slug>.html
```

So **changing the categories or date of a published post changes its URL**, which
breaks inbound links and search results. Set them once and leave them.

### Tags: one topic tag on top of the specific ones

Tags are free-form and hyphenated, and most describe one paper's contribution
(`Fine-Grained-Expert-Segmentation`). Those are a good index but they connect
nothing: 220 of 264 tags were used by exactly one post, and since
`_plugins/related_posts.rb` requires a **shared** tag, 11 posts got no related
reading at all — including four graph-RAG papers that share no tag with each
other.
Tags are free-form and hyphenated, and a tag phrased as one paper's contribution
(`Fine-Grained-Expert-Segmentation`) can only ever apply to that paper. Those
make a precise index and connect nothing, and `_plugins/related_posts.rb`
requires a **shared** tag — so a post tagged only that way ships with no
"Related reading" block at all.

So also give each post at least one tag from the controlled topic layer:

Expand All @@ -169,18 +176,12 @@ Retrieval-Augmented-Generation
```

Keep the specific tags — they say something the topic tag does not, and dropping
them would move live `/tags/` anchors. Before inventing a topic tag, check
whether one of the above (or an existing tag used by 2+ posts) already covers it:
`Agentic-Architecture`, `Agentic-Patterns` and `Agentic-Infrastructure` were three
names for one thing, which is why that cluster had no links.

Jekyll combines them with the date to build the output path:
them would move live `/tags/` anchors. **Add the topic tag, don't swap for it.**

```
categories: ["Paper Reviews", "Language-Models"] + date: 2025-01-23
_site/paper reviews/language-models/2025/01/23/<slug>.html
```
Before coining a new topic tag, check that nothing above already covers it. Three
names for one idea (`Agentic-Architecture`, `Agentic-Patterns`,
`Agentic-Infrastructure`) leave every post holding a tag no other post shares,
which is the same as having no topic tag at all.

### Math: always use `$$…$$`

Expand All @@ -194,40 +195,42 @@ dollar signs like `$10M` are fine — they're not math.)

### Validate before pushing

These are the four gates CI runs, in the same order. Build to a throwaway
directory rather than `_site/`, for the reason in the note below:

```bash
ruby test/run_all.rb # plugin logic still correct?
bundle exec jekyll build # does it build clean?
bundle exec htmlproofer ./_site --disable-external # any broken links/images?
script/validate-site.sh # sitemap, feed, metadata, headings
ruby test/run_all.rb # plugin logic still correct?
bundle exec jekyll build --strict-front-matter \
--destination /tmp/site-verify # does it build clean?
bundle exec htmlproofer /tmp/site-verify --disable-external \
--allow-hash-href --no-enforce-https # broken links, images, anchors?
script/validate-site.sh /tmp/site-verify # sitemap, feed, metadata, headings
```

CI runs the same three checks, so catching it locally saves a failed deploy.

`test/` covers `_plugins/` — the description derivation, the read-time estimate,
and the lazy-image rewrite. Plain `ruby`, not `bundle exec`: the plugins guard
their Jekyll/Liquid registration behind `defined?` so their logic loads
standalone, and minitest ships with Ruby. **Anything you change in `_plugins/`
changes every page on the site**, so add a case there before changing behaviour.

> **If the checks report something impossible, look for a running `jekyll serve`
> **If a check reports something impossible, look for a running `jekyll serve`
> first.** It watches the tree and rewrites `_site/` behind you, it overrides
> `site.url` with `http://localhost:4000` (so every sitemap URL looks wrong), and
> it keeps the `_config.yml` it started with — so `exclude` entries added since
> then don't apply. Either stop it, or build somewhere else:
> it holds the `_config.yml` it started with — so `exclude` entries added since
> then don't apply. Building elsewhere sidesteps all three:
>
> ```bash
> ps aux | grep '[j]ekyll serve'
> bundle exec jekyll build --destination /tmp/site-verify
> script/validate-site.sh /tmp/site-verify
> ```

`test/` unit-tests the pure logic in `_plugins/` — one file per plugin. Plain
`ruby`, not `bundle exec`: each plugin guards its Jekyll/Liquid registration
behind `defined?` so the logic loads standalone, and minitest ships with Ruby.
**Anything you change in `_plugins/` changes every page on the site**, so add a
case before changing behaviour.

---

## Deployment

`.github/workflows/jekyll.yml` runs on **pull requests to `main` as well as
pushes to it**, so the four gates below block a bad merge instead of only
reporting one. Steps 1–4 run on both; step 5 is skipped for pull requests. It:
pushes to it**, so the gates below block a bad merge rather than merely reporting
one after the fact. Steps 1–4 run on both events; step 5 is skipped for pull
requests. In order, it:

1. runs **`ruby test/run_all.rb`** (the `_plugins/` unit tests),
2. builds the site with `JEKYLL_ENV=production`,
Expand All @@ -240,8 +243,8 @@ reporting one. Steps 1–4 run on both; step 5 is skipped for pull requests. It:
no authoring sources published — and
5. deploys to GitHub Pages.

If the workflow fails, it's almost always step 3 or 4 — open the Actions log,
which names the exact link, image, or page. No manual deploy step is needed.
A failure is almost always step 3 or 4; the Actions log names the exact link,
image, or page. There is no manual deploy step.

> **⚠ Don't add `google*.html` / `naver*.html` to `_config.yml`'s `exclude`.**
> They're Search Console / Naver ownership-verification tokens that must ship to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: >-
Build·Deploy·Assess 세 층으로 열어 하네스 체크리스트의 어디를 채우고 어디를 비워 두었는지 짚습니다.
date: 2026-04-12 12:00:00
categories: ["Insights", "Agentic-AI"]
tags: ["AgentCore", "AWS-Bedrock", "Harness-Engineering", "Agentic-Infrastructure", "Model-Context-Protocol", "Cedar-Policy", "Managed-RAG", "Agent-Registry", "Agentic-AI"]
tags: ["AgentCore", "AWS-Bedrock", "Harness-Engineering", "Agentic-Infrastructure", "MCP", "Model-Context-Protocol", "Cedar-Policy", "Managed-RAG", "Agent-Registry", "Agentic-AI"]
cover: /assets/images/insights.jpg
use_math: false
---
Expand Down
Loading
Loading