Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4a34c31
ci: upgrade GitHub Actions to Node 24
hellices Sep 13, 2026
4853f87
test: harden workflow contract checks
hellices Sep 13, 2026
75e44e9
test(docs): inventory pre-Pages content lineage
hellices Sep 13, 2026
c8debdb
fix(docs): reject ambiguous inventory and shallow history
hellices Sep 13, 2026
b1ce99a
test(docs): verify pre-Pages content preservation
hellices Sep 13, 2026
99b74f2
fix(docs): bind preservation approvals to current evidence
hellices Sep 13, 2026
7bfeab6
fix(docs): require exact links and public tracked evidence
hellices Sep 13, 2026
d28b8c5
fix(docs): isolate HTML and honor image escape parity
hellices Sep 13, 2026
77d98bd
fix(docs): derive preservation semantics from Markdown renderer
hellices Sep 13, 2026
84a5cf8
fix(docs): share repository semantic renderer configuration
hellices Sep 13, 2026
9ebda46
test(docs): audit migrated site visibility
hellices Sep 13, 2026
8180190
fix(docs): close built-site audit review gaps
hellices Sep 13, 2026
eef1cc1
fix(docs): validate URL spellings and MkDocs page aliases
hellices Sep 13, 2026
908443a
fix(docs): reject ambiguous raw leading slash references
hellices Sep 13, 2026
b541202
ci: enforce pre-Pages preservation audit
hellices Sep 13, 2026
aadcfc0
fix(docs): tighten audit workflow contract
hellices Sep 13, 2026
492d3ce
fix(docs): close final preservation audit gaps
hellices Sep 13, 2026
6fa2279
fix(docs): share finalized visibility semantics
hellices Sep 13, 2026
6d90d83
fix(docs): separate historical and current audit coverage
hellices Sep 14, 2026
2488cf6
fix(docs): preserve Git status for reviewed dispositions
hellices Sep 14, 2026
3a432f0
fix(docs): enforce safe audit inputs and workflow counts
hellices Sep 14, 2026
150894e
test(docs): fail closed on audit path mentions
hellices Sep 14, 2026
3d9e6e1
test(docs): enforce literal audit references
hellices Sep 14, 2026
ef1b233
fix(docs): bind rename lineage and model implied HTML ends
hellices Sep 14, 2026
d67ac06
fix(docs): reject foster ambiguity and isolate raw content
hellices Sep 14, 2026
1a2f09b
fix(docs): restore native disclosures and require audit gates
hellices Sep 14, 2026
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
9 changes: 7 additions & 2 deletions .github/workflows/docs-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ jobs:
timeout-minutes: 15
steps:
- name: Check out repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
Expand All @@ -40,3 +42,6 @@ jobs:

- name: Validate search index
run: python scripts/docs/validate_search_index.py

- name: Audit pre-Pages content preservation
run: python scripts/docs/audit_pre_pages.py
2 changes: 1 addition & 1 deletion .github/workflows/oryx-python-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Pull Oryx build image
run: docker pull mcr.microsoft.com/oryx/build:github-actions-debian-bullseye
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ jobs:
timeout-minutes: 15
steps:
- name: Check out repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
Expand All @@ -47,11 +49,14 @@ jobs:
- name: Validate search index
run: python scripts/docs/validate_search_index.py

- name: Audit pre-Pages content preservation
run: python scripts/docs/audit_pre_pages.py

- name: Configure Pages
uses: actions/configure-pages@v5
uses: actions/configure-pages@v6

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
uses: actions/upload-pages-artifact@v5
with:
path: site

Expand All @@ -68,4 +73,4 @@ jobs:
steps:
- name: Deploy to Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,10 @@ python scripts/docs/validate_links.py
python scripts/docs/validate_public_safety.py
mkdocs build --strict
python scripts/docs/validate_search_index.py
python scripts/docs/audit_pre_pages.py
```

테스트나 검증 실패를 무시하거나 생성된 `site/` 및 검색 인덱스를 커밋하지
않는다. sample 애플리케이션의 별도 테스트나 의존성은 해당 sample 변경
범위에서만 실행한다.
않는다. `python scripts/docs/audit_pre_pages.py`는 전체 Git 이력이
필요하며 자세한 기준과 실행 지침은 `docs/contributing/index.md`를 따른다.
sample 애플리케이션의 별도 테스트나 의존성은 해당 sample 변경 범위에서만 실행한다.
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ python scripts/docs/validate_links.py
python scripts/docs/validate_public_safety.py
mkdocs build --strict
python scripts/docs/validate_search_index.py
python scripts/docs/audit_pre_pages.py
```

이 감사는 과거 공개 콘텐츠와 호환 URL 보존을 확인하며 전체 Git 이력이
필요합니다. 자세한 기준과 실행 지침은
[상세 기여 지침](docs/contributing/index.md)을 따릅니다.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,8 @@ python -m venv .venv

자세한 작성·검증 규칙은
[공개 문서 작성 계약](docs/contributing/index.md)을 확인하세요.
검색 인덱스 검증 다음에는 `python scripts/docs/audit_pre_pages.py`를
실행하며, 이 감사는 전체 Git 이력이 필요합니다. 자세한 기준과 실행 지침도
[공개 문서 작성 계약](docs/contributing/index.md)에서 확인하세요.

> 이 저장소와 Pages는 공개되어 있습니다. 고객·사용자 식별자, 구독·테넌트 ID, 비밀, 내부 URL 또는 승인되지 않은 화면 캡처를 커밋하지 마세요.
46 changes: 44 additions & 2 deletions docs/contributing/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ publish:
`downloads/index.md` 같은 원본 자산은 해당 파일 경로로 직접 링크합니다.
`downloads/`처럼 문서 디렉터리로 줄여 쓰면 다운로드 자산을 가리키지 않습니다.
공개 target의 경로 구성 요소는 어느 깊이에서도 `.`으로 시작할 수 없습니다.
[Pages artifact 패키징](https://github.com/actions/upload-pages-artifact/blob/v4/action.yml)이
숨김 파일과 숨김 디렉터리를 제외하므로, 이런 target은 빌드 전에 거부합니다.
[Pages artifact 패키징](https://github.com/actions/upload-pages-artifact/blob/v5/action.yml)이
기본적으로 숨김 파일과 숨김 디렉터리를 제외하므로, 이런 target은 빌드 전에 거부합니다.
sample 원본 payload 내부의 숨김 파일은 허용하며 원본 폴더는 계속 게시에서 제외합니다.
페이지 본문과 링크 텍스트는 기존처럼 검색됩니다. `used_by`는 sample card의
표시 위치만 결정하며 `publish`와 독립적입니다.
Expand Down Expand Up @@ -300,7 +300,49 @@ python scripts/docs/validate_links.py
python scripts/docs/validate_public_safety.py
mkdocs build --strict
python scripts/docs/validate_search_index.py
python scripts/docs/audit_pre_pages.py
```

`audit_pre_pages.py`는 고정된 pre-Pages 기준선과 현재 built site를 함께
대조해 과거 공개 콘텐츠와 호환 URL이 계속 보존되는지 검사합니다.
보존 inventory는 `a4e6801` 시점의 **기준선 문서 62개**를 현재 canonical
문서에 일대일로 연결합니다. 신규 문서는 이 기준선 inventory에 추가하지
않으며, 현재 문서 수가 늘어났다는 이유로 감사가 실패하지 않습니다.
각 연결은 `rename_similarity`로 계산한 기준선 → 최초 Pages commit의
실제 Git `R` 기록과 원본·대상 경로가 일치해야 합니다. 양쪽 파일이
존재한다는 사실만으로는 이관 계보를 인정하지 않습니다.
과거 구조 비교와 JSON의 `document_count`·`details.documents`는 이 62개만
대상으로 합니다. `current_document_count`는 현재 카탈로그에서 계산합니다.
검토된 disposition은 Git에서 실제로 삭제된 기준선 경로에만 적용합니다.
비어 있지 않은 `current_paths`는 `HEAD`에 저장된 `docs/services/**` 또는
`tests/docs/**`의 일반 소스 파일이어야 합니다. 추적되지 않은 파일, ignore된
파일, 생성 결과물과 심볼릭 링크는 대체 근거로 사용할 수 없습니다.
빈 `current_paths`는 삭제된 로컬 상태를 제외할 때만 허용합니다.
가시성 감사는 닫힌 `<details>`를 첫 직접 자식 `<summary>` 또는 브라우저의
기본 컨트롤로 펼칠 수 있는지 검사합니다. 작성된 summary가 없어도
컨트롤이 보이고 상호작용 가능하면 본문을 인정합니다. 상속된 `inert`,
`hidden`, `display:none`, `aria-hidden` 등의 접근 제한은 계속 반영합니다.
다른 요소 뒤에 오는 첫 `<summary>`도 인정하며, 이미 `open`인 본문은
별도로 가시성을 확인합니다.

전체 감사는 기준선 밖의 신규 문서까지 포함해 현재 canonical 문서 **전체**의
본문 가시성, 검색, 서비스별 주제 진입점, 글 찾기 연결과 로컬 자산을 검사합니다.
각 문서가 선언한 모든 `redirect_from`도 확인하며, inventory에 기록된
기준선 Pages 경로 62개는 계속 필수입니다. 현재 문서가 66개인 경우의 성공
출력은 다음과 같습니다. 현재 문서 수는 고정된 제한이 아닙니다.

```text
Audited 359 baseline files and 73 Markdown files: 62/62 baseline documents mapped and preserved; 66 current documents searchable and visible; declared redirects and local assets verified.
```

`--content-only`는 기준선 구조 보존만 검사하며 built site를 확인했다고
표현하지 않습니다. 이 검사는
`a4e6801`과 `9ace9667` commit object를 직접 읽으므로 전체 Git 이력이
필수입니다. 로컬 clone이 얕으면 검사를 건너뛰지 말고
`git fetch --unshallow` 또는 동등한 전체 이력 fetch를 수행한 뒤 다시
실행합니다. CI에서는 checkout `fetch-depth: 0`으로 같은 조건을 보장합니다.
필수 감사 step과 이를 포함한 validate/build job에는 실행을 건너뛸 수 있는
`if`를 두지 않으며, `continue-on-error`로 감사 실패를 무시하지 않습니다.

생성된 `site/`과 검색 인덱스는 커밋하지 않습니다. 실패한 검증을 무시하지
않습니다.
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ mysql -h <new-db> -e "

> **Phase 5 (재배포) 불필요** — `DB_HOST=primary.db.<prefix>.internal` 은 CNAME 교체 후에도 동일.

<details>
<details markdown="1">
<summary>Rollback 절차 보기</summary>

> Rollback 가능 조건: new-db에 write가 발생하지 않은 시점(= super_read_only ON 오류로만 발생). new-db에 이미 데이터가 작성된 경우는 데이터 동기화 후 교체해야 하며, 데이터 팀 개입이 필요합니다.
Expand Down Expand Up @@ -351,7 +351,7 @@ mysql -h <old-db> -e "SET GLOBAL super_read_only = OFF;"

## 시뮬레이션 (`simulation/`)

<details>
<details markdown="1">
<summary>시뮬레이션 구성, 설계 결정, 실행 순서 보기</summary>

### 목적
Expand Down Expand Up @@ -622,7 +622,7 @@ LIMIT 1;

→ **사전에 new-db에서 전체 쿼리 regression test 수행 필수**

<details>
<details markdown="1">
<summary>5. Rollback 절차</summary>

커트오버 후 문제 발생 시 아래 순서로 원복합니다.
Expand Down
4 changes: 4 additions & 0 deletions docs/services/microsoft-foundry/agent-memory/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ redirect_from:

## 목적별 빠른 경로

이관 전 문서별 상세 읽기 목표와 대상 독자는
[원문 독자 지도](https://github.com/hellices/devguidesample/blob/main/docs/services/microsoft-foundry/agent-memory/samples/research-artifacts/README.md#historical-reader-map-pre-pages)에
역사적 기록으로 보존한다.
Comment on lines +56 to +58
Comment on lines +56 to +58

**시간이 없다면** → [06. 커머스 적용 설계](commerce/index.md) 만 읽는다. 나머지 문서의 결론이 여기 수렴한다.

**설계를 시작한다면**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,22 @@
This sample contains the editable SVG diagrams owned by the Agent Memory topic
package. They support its memory taxonomy, architecture patterns, retrieval
pipeline, production tiers, and commerce blueprint.

## Historical reader map (pre-Pages)

The pre-Pages snapshot `a4e680116db1016a698e64baae9efde858a8eafa`
included the following detailed reading objectives and audiences. The topic's
generated navigation replaced the old document list, but did not retain these
audience assignments. This is a historical research map, not a current product-support statement.
Links now point to the corresponding canonical documents.

### 문서 구성

| 문서 | 내용 | 대상 |
|------|------|------|
| **[01. 메모리 분류 체계](../../taxonomy/index.md)** | Agent Memory **8유형 통합 정의**, 유형별 **저장소 선택지**와 Azure 매핑, Retention 정책, 30기법 6패밀리 지도 | 전원 |
| **[02. 아키텍처 패턴](../../architecture-patterns/index.md)** | Single-Store / Dual-Store / Tiered / Graph-Augmented / Full Cognitive 5패턴, 비교표, 선택 결정 트리 | 아키텍트 |
| **[03. 파이프라인과 검색](../../pipeline-retrieval/index.md)** | 쓰기 경로(추출→중복·모순 해소→라우팅) / 읽기 경로(hybrid search→RRF→rerank→MMR→temporal), 단계별 지연 비용 | 개발자 |
| **[04. 프레임워크 비교](../../frameworks/index.md)** | Mem0 · Zep · Graphiti · Letta(MemGPT) · Cognee · Azure AI Search, **자체 구현 vs 도입 판단 기준** | 의사결정자 |
| **[05. 프로덕션과 평가](../../production-evaluation/index.md)** | Tiered storage, PII·GDPR, TTL·샤딩·관측성·비용, 평가 지표, LoCoMo/LongMemEval 벤치마크 | SRE / 개발자 |
| **[06. 커머스 적용 설계](../../commerce/index.md)** | **메모리 스키마 · 지연 예산 · 개인화 강도 단계화 · 안티패턴 · Phase 0~4 로드맵 · 기술+비즈니스 지표** | 전원 (핵심) |
86 changes: 86 additions & 0 deletions scripts/docs/audit_pre_pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""Audit fixed pre-Pages preservation and visibility of the current canonical corpus."""

from __future__ import annotations

import argparse
from collections.abc import Mapping
from dataclasses import fields, is_dataclass
import json
from pathlib import Path, PurePath
import sys
from uuid import uuid4


REPO_ROOT = Path(__file__).resolve().parents[2]
if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))

from scripts.docs.pre_pages import PreservationAuditResult, audit_repository


def _json_value(value: object) -> object:
if is_dataclass(value):
return {field.name: _json_value(getattr(value, field.name)) for field in fields(value)}
if isinstance(value, Mapping):
return {str(key): _json_value(item) for key, item in value.items()}
if isinstance(value, (tuple, list)):
return [_json_value(item) for item in value]
if isinstance(value, PurePath):
return value.as_posix()
return value


def write_audit_json(path: Path, result: PreservationAuditResult) -> None:
"""Replace a report only after the entire new JSON document has been written."""
path.parent.mkdir(parents=True, exist_ok=True)
sibling = path.with_name(f".{path.name}.{uuid4().hex}.tmp")
try:
with sibling.open("x", encoding="utf-8") as stream:
stream.write(json.dumps(_json_value(result), ensure_ascii=False, indent=2, sort_keys=True) + "\n")
sibling.replace(path)
finally:
sibling.unlink(missing_ok=True)


def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-root", type=Path, default=REPO_ROOT)
parser.add_argument("--site-dir", type=Path)
parser.add_argument("--inventory", type=Path)
parser.add_argument("--json-output", type=Path)
parser.add_argument("--content-only", action="store_true")
args = parser.parse_args(argv)
root = args.repo_root.resolve()
site = args.site_dir if args.site_dir is not None else Path("site")
inventory = args.inventory if args.inventory is not None else Path("scripts/docs/pre_pages_inventory.yml")
result = audit_repository(
root, root / site, root / inventory, content_only=args.content_only,
)
if args.json_output:
try:
write_audit_json(args.json_output, result)
except (OSError, ValueError) as error:
print(f"{args.json_output}: cannot write audit JSON: {error}")
return 1
for warning in result.warnings:
print(f"Warning: {warning}")
if result.errors:
for error in result.errors:
print(error.replace("\r", "\\r").replace("\n", "\\n"))
return 1
summary = (
f"Audited {result.baseline_file_count} baseline files and "
f"{result.baseline_markdown_count} Markdown files: "
f"{result.preserved_documents}/{result.document_count} baseline documents mapped and preserved"
)
print(summary + (
f" (content-only; {result.current_document_count} current documents; built site not inspected)."
if args.content_only else
f"; {result.current_document_count} current documents searchable and visible; "
"declared redirects and local assets verified."
))
return 0


if __name__ == "__main__":
raise SystemExit(main())
20 changes: 20 additions & 0 deletions scripts/docs/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import sys
from typing import Any, Mapping

from jinja2 import ChoiceLoader, DictLoader
from mkdocs.structure.files import File, InclusionLevel
from mkdocs.structure import StructureItem
from mkdocs.structure.nav import Navigation, Section
Expand Down Expand Up @@ -376,6 +377,25 @@ def on_page_markdown(markdown: str, page: Any, config: Mapping[str, Any], files:
return markdown


def on_env(env: Any, config: Mapping[str, Any], files: Any) -> Any:
"""Keep Material's sharing anchor without its executable placeholder URL."""
theme = config.get("theme", {})
if theme.get("name") != "material" or "search.share" not in theme.get("features", []):
return env
template = "partials/search.html"
source, _, _ = env.loader.get_source(env, template)
safe_source = re.sub(
r'<a\b[^>]*data-md-component="search-share"[^>]*>',
lambda match: match[0].replace('href="javascript:void(0)"', 'href="#"'),
source,
)
Comment on lines +386 to +391
if safe_source != source:
env.loader = ChoiceLoader([DictLoader({template: safe_source}), env.loader])
if env.cache is not None:
env.cache.clear()
return env


def on_post_page(output: str, page: Any, config: Mapping[str, Any]) -> str:
"""Move generated redirect metadata into the final HTML head."""
page_file = getattr(page, "file", None)
Expand Down
Loading
Loading