From d278b729ea37fb9e36d404d664bc0044699024d4 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 27 Mar 2026 19:19:39 +0800 Subject: [PATCH 1/2] Add Ivan Bazi Architect experimental skill --- .../ivan-bazi-architect/LICENSE.txt | 21 ++++ .../ivan-bazi-architect/README.md | 32 +++++ .../ivan-bazi-architect/SKILL.md | 38 ++++++ .../ivan-bazi-architect/agents/openai.yaml | 4 + .../references/core-books.md | 25 ++++ .../references/workflow.md | 32 +++++ .../scripts/build_pdf_index.py | 111 ++++++++++++++++++ 7 files changed, 263 insertions(+) create mode 100644 skills/.experimental/ivan-bazi-architect/LICENSE.txt create mode 100644 skills/.experimental/ivan-bazi-architect/README.md create mode 100644 skills/.experimental/ivan-bazi-architect/SKILL.md create mode 100644 skills/.experimental/ivan-bazi-architect/agents/openai.yaml create mode 100644 skills/.experimental/ivan-bazi-architect/references/core-books.md create mode 100644 skills/.experimental/ivan-bazi-architect/references/workflow.md create mode 100644 skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py diff --git a/skills/.experimental/ivan-bazi-architect/LICENSE.txt b/skills/.experimental/ivan-bazi-architect/LICENSE.txt new file mode 100644 index 00000000..a754f053 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Ivan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/skills/.experimental/ivan-bazi-architect/README.md b/skills/.experimental/ivan-bazi-architect/README.md new file mode 100644 index 00000000..fdd07460 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/README.md @@ -0,0 +1,32 @@ +# Ivan Bazi Architect + +Codex skill for BaZi-oriented decision diagnostics with indexed classical references. + +## Resource Path + +Default source directory: + +`/Users/ivan/Desktop/电子书/ddddddd/` + +## Core References + +- 三命通会(基础术语与多维意象) +- 穷通宝鉴(调候准则,SW-1) +- 滴天髓 / 子平真诠(能量流通与格局判定,SW-2) +- 八字提要(实战回退与执行指南) +- 周易译注(边界与可证伪框架) + +## Quick Start + +1. Build index: + - `python3 scripts/build_pdf_index.py --source-dir "/Users/ivan/Desktop/电子书/ddddddd/" --out references/pdf-index.jsonl` +2. Invoke skill in Codex and request SW-1/SW-2/SW-3 diagnosis. +3. Ask for output in publish format (X thread / short brief / audit memo). + +## Install In Codex + +`$skill-installer install https://github.com/openai/skills/tree/main/skills/.experimental/ivan-bazi-architect` + +## Boundary + +This skill is for reflective strategy support with citations and uncertainty notes. It is not a deterministic guarantee engine. diff --git a/skills/.experimental/ivan-bazi-architect/SKILL.md b/skills/.experimental/ivan-bazi-architect/SKILL.md new file mode 100644 index 00000000..391a5503 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/SKILL.md @@ -0,0 +1,38 @@ +--- +name: ivan-bazi-architect +description: Ivan's Bazi decision-architecture skill for structured diagnosis and strategy planning from classical BaZi references. Use when users ask for 八字分析、调候优先级、格局判断、冲合克害压力测试、或基于命理语料做审计/摘要/策略建议,并需要可追溯的引用与边界约束。 +--- + +# Ivan Bazi Architect + +Convert classical BaZi references into a structured, auditable decision workflow. + +## Workflow + +1. Load source knowledge. + - Use `references/core-books.md` to map canonical books and filename variants. + - Default source path: `/Users/ivan/Desktop/电子书/ddddddd/`. +2. Build or refresh index. + - Run `scripts/build_pdf_index.py` to extract searchable PDF metadata and snippets. + - Keep output under local skill workspace (do not overwrite source PDFs). +3. Run layered diagnosis. + - SW-1 (调候层): identify first-priority environmental resource. + - SW-2 (格局层): identify dominant system logic and flow chain. + - SW-3 (反馈层): run conflict/combination stress checks. +4. Trigger circuit-breaker rules. + - Detect high-risk 用神受损 scenarios. + - Emit warning tier and fallback options. +5. Publish output with boundaries. + - Provide concise recommendations with references and confidence levels. + - Keep ethical boundary: advisory for reflection/decision support, not deterministic fate claims. + +## Output Contract + +Return in this structure: + +1. Input summary (what data was analyzed). +2. SW-1 / SW-2 / SW-3 findings. +3. Circuit-breaker alerts (if any). +4. Recommended actions (primary + fallback). +5. Source citations (book + section snippet). +6. Boundary note (scope, uncertainty, ethical limits). diff --git a/skills/.experimental/ivan-bazi-architect/agents/openai.yaml b/skills/.experimental/ivan-bazi-architect/agents/openai.yaml new file mode 100644 index 00000000..2262a1dd --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Ivan Bazi Architect" + short_description: "BaZi diagnosis workflow with indexed classics and guardrails." + default_prompt: "Use Ivan Bazi Architect to index the configured BaZi PDFs, run SW-1/SW-2/SW-3 diagnosis, and produce a cited, bounded strategy brief." diff --git a/skills/.experimental/ivan-bazi-architect/references/core-books.md b/skills/.experimental/ivan-bazi-architect/references/core-books.md new file mode 100644 index 00000000..2cd23a69 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/references/core-books.md @@ -0,0 +1,25 @@ +# Core Books Map + +Default source path: + +`/Users/ivan/Desktop/电子书/ddddddd/` + +Use keyword matching because filenames may include suffixes like `(Z-Library)`, `_compressed`, uppercase `.PDF`, or author notes. + +## Canonical Mapping + +1. 三命通会 + - Match keywords: `三命通会` +2. 穷通宝鉴 + - Match keywords: `穷通宝鉴` +3. 滴天髓 / 子平真诠 + - Match keywords: `滴天髓`, `子平真詮`, `子平真诠` +4. 八字提要(韦千里) + - Match keywords: `八字提要`, `韦千里` +5. 周易译注 + - Match keywords: `周易译注` + +## Suggested Citation Format + +- `书名 / 文件名 / 页码(若可得) / 摘录` +- Keep excerpt short and directly relevant to the claim. diff --git a/skills/.experimental/ivan-bazi-architect/references/workflow.md b/skills/.experimental/ivan-bazi-architect/references/workflow.md new file mode 100644 index 00000000..97571268 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/references/workflow.md @@ -0,0 +1,32 @@ +# Diagnostic Workflow (SW-1 / SW-2 / SW-3) + +## SW-1 调候层 + +- Determine first-priority environmental resource constraints. +- Prioritize survival/stability conditions before optimization. + +## SW-2 格局层 + +- Identify dominant logic and viable flow chain. +- Reject high-level claims that break the actual flow path. + +## SW-3 反馈层 + +- Evaluate冲/合/克/害 interactions as stress signals. +- Produce risk tier and fallback plan when critical links are damaged. + +## Circuit Breaker Rules + +- Trigger L4 warning when 用神 support is significantly degraded. +- Always output: + - primary mitigation + - fallback mitigation + - monitoring signal to revisit the decision + +## Publishing Style + +- Output should be concise, structured, and citation-backed. +- Adapt format to: + - short X post thread + - knowledge-community digest + - executive memo diff --git a/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py b/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py new file mode 100644 index 00000000..adf5527a --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +""" +Build a lightweight JSONL index from BaZi reference PDFs. + +Example: + python3 scripts/build_pdf_index.py \ + --source-dir "/Users/ivan/Desktop/电子书/ddddddd/" \ + --out references/pdf-index.jsonl +""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Iterable + + +KEYWORDS = { + "三命通会": ["三命通会"], + "穷通宝鉴": ["穷通宝鉴"], + "滴天髓_子平真诠": ["滴天髓", "子平真詮", "子平真诠"], + "八字提要": ["八字提要", "韦千里"], + "周易译注": ["周易译注"], +} + + +def iter_pdfs(source_dir: Path) -> Iterable[Path]: + for p in sorted(source_dir.iterdir()): + if p.is_file() and p.suffix.lower() == ".pdf": + yield p + + +def detect_tags(file_name: str) -> list[str]: + tags: list[str] = [] + for canonical, kws in KEYWORDS.items(): + if any(kw in file_name for kw in kws): + tags.append(canonical) + return tags + + +def read_pdf_sample(pdf_path: Path, max_pages: int, max_chars: int) -> tuple[int, str]: + try: + from pypdf import PdfReader + except Exception as exc: # pragma: no cover + raise RuntimeError( + "pypdf is required. Install with: python3 -m pip install pypdf" + ) from exc + + reader = PdfReader(str(pdf_path)) + text_parts: list[str] = [] + page_total = len(reader.pages) + limit = min(max_pages, page_total) + for i in range(limit): + txt = reader.pages[i].extract_text() or "" + if txt: + text_parts.append(txt.strip()) + sample = "\n".join(text_parts).strip() + if len(sample) > max_chars: + sample = sample[:max_chars] + return page_total, sample + + +def main() -> int: + parser = argparse.ArgumentParser(description="Build PDF metadata index JSONL") + parser.add_argument("--source-dir", required=True, help="Directory with source PDFs") + parser.add_argument( + "--out", + default="references/pdf-index.jsonl", + help="Output JSONL path (default: references/pdf-index.jsonl)", + ) + parser.add_argument("--max-pages", type=int, default=6, help="Pages to sample per file") + parser.add_argument("--max-chars", type=int, default=6000, help="Max chars per sample") + args = parser.parse_args() + + source_dir = Path(args.source_dir).expanduser().resolve() + out_path = Path(args.out).resolve() + out_path.parent.mkdir(parents=True, exist_ok=True) + + if not source_dir.exists() or not source_dir.is_dir(): + raise SystemExit(f"Source directory does not exist: {source_dir}") + + indexed = 0 + with out_path.open("w", encoding="utf-8") as fout: + for pdf in iter_pdfs(source_dir): + page_count, sample = read_pdf_sample(pdf, args.max_pages, args.max_chars) + row = { + "file_name": pdf.name, + "file_path": str(pdf), + "page_count": page_count, + "tags": detect_tags(pdf.name), + "sample_text": sample, + } + fout.write(json.dumps(row, ensure_ascii=False) + "\n") + indexed += 1 + + summary_path = out_path.with_suffix(".summary.json") + summary = { + "source_dir": str(source_dir), + "indexed_files": indexed, + "index_path": str(out_path), + } + summary_path.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8") + + print(f"Indexed {indexed} PDFs -> {out_path}") + print(f"Summary -> {summary_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From bafe7b5065e946c28915da58c35f58fee22ef73b Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 28 Mar 2026 04:21:40 +0800 Subject: [PATCH 2/2] align ivan-bazi-architect with official skill best practices --- .../ivan-bazi-architect/README.md | 23 ++++++++++-- .../ivan-bazi-architect/SKILL.md | 10 +++-- .../ivan-bazi-architect/agents/openai.yaml | 4 +- .../ivan-bazi-architect/config.example.json | 5 +++ .../references/core-books.md | 5 ++- .../ivan-bazi-architect/references/gotchas.md | 24 ++++++++++++ .../scripts/build_pdf_index.py | 37 +++++++++++++++++-- 7 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 skills/.experimental/ivan-bazi-architect/config.example.json create mode 100644 skills/.experimental/ivan-bazi-architect/references/gotchas.md diff --git a/skills/.experimental/ivan-bazi-architect/README.md b/skills/.experimental/ivan-bazi-architect/README.md index fdd07460..7164f221 100644 --- a/skills/.experimental/ivan-bazi-architect/README.md +++ b/skills/.experimental/ivan-bazi-architect/README.md @@ -2,11 +2,19 @@ Codex skill for BaZi-oriented decision diagnostics with indexed classical references. -## Resource Path +## Resource Setup -Default source directory: +Configure your local PDF source directory in a local `config.json` (copy from `config.example.json`): -`/Users/ivan/Desktop/电子书/ddddddd/` +```json +{ + "source_dir": "/path/to/your/bazi-pdfs", + "output_format": "audit_memo", + "citation_mode": "book_file_snippet" +} +``` + +You can also pass `--source-dir` directly to the index script. ## Core References @@ -19,7 +27,8 @@ Default source directory: ## Quick Start 1. Build index: - - `python3 scripts/build_pdf_index.py --source-dir "/Users/ivan/Desktop/电子书/ddddddd/" --out references/pdf-index.jsonl` + - `python3 scripts/build_pdf_index.py --source-dir "/path/to/your/bazi-pdfs" --out references/pdf-index.jsonl` + - Or use config fallback: `python3 scripts/build_pdf_index.py --config config.json --out references/pdf-index.jsonl` 2. Invoke skill in Codex and request SW-1/SW-2/SW-3 diagnosis. 3. Ask for output in publish format (X thread / short brief / audit memo). @@ -30,3 +39,9 @@ Default source directory: ## Boundary This skill is for reflective strategy support with citations and uncertainty notes. It is not a deterministic guarantee engine. + +## Contributor Notes + +- Keep personal absolute paths out of committed files. +- Store local source directories in uncommitted `config.json`. +- Add new failure patterns to `references/gotchas.md` when you see repeat model mistakes. diff --git a/skills/.experimental/ivan-bazi-architect/SKILL.md b/skills/.experimental/ivan-bazi-architect/SKILL.md index 391a5503..927617a6 100644 --- a/skills/.experimental/ivan-bazi-architect/SKILL.md +++ b/skills/.experimental/ivan-bazi-architect/SKILL.md @@ -1,6 +1,6 @@ --- name: ivan-bazi-architect -description: Ivan's Bazi decision-architecture skill for structured diagnosis and strategy planning from classical BaZi references. Use when users ask for 八字分析、调候优先级、格局判断、冲合克害压力测试、或基于命理语料做审计/摘要/策略建议,并需要可追溯的引用与边界约束。 +description: Use when users explicitly ask for 八字/命理 style analysis, SW-1/SW-2/SW-3 structured diagnosis, or citation-backed summaries from classical BaZi references. Do not trigger for general scientific, legal, medical, or deterministic certainty requests. --- # Ivan Bazi Architect @@ -9,11 +9,13 @@ Convert classical BaZi references into a structured, auditable decision workflow ## Workflow -1. Load source knowledge. +1. Load source knowledge and setup. - Use `references/core-books.md` to map canonical books and filename variants. - - Default source path: `/Users/ivan/Desktop/电子书/ddddddd/`. + - Use `config.example.json` as the setup template (`source_dir`, output preferences). + - Prefer a local, user-managed `config.json` that is not committed. 2. Build or refresh index. - Run `scripts/build_pdf_index.py` to extract searchable PDF metadata and snippets. + - CLI argument `--source-dir` overrides config. - Keep output under local skill workspace (do not overwrite source PDFs). 3. Run layered diagnosis. - SW-1 (调候层): identify first-priority environmental resource. @@ -25,6 +27,8 @@ Convert classical BaZi references into a structured, auditable decision workflow 5. Publish output with boundaries. - Provide concise recommendations with references and confidence levels. - Keep ethical boundary: advisory for reflection/decision support, not deterministic fate claims. +6. Apply gotchas checks before final answer. + - Use `references/gotchas.md` to avoid overclaiming, weak citations, and unsupported certainty language. ## Output Contract diff --git a/skills/.experimental/ivan-bazi-architect/agents/openai.yaml b/skills/.experimental/ivan-bazi-architect/agents/openai.yaml index 2262a1dd..e9e392a8 100644 --- a/skills/.experimental/ivan-bazi-architect/agents/openai.yaml +++ b/skills/.experimental/ivan-bazi-architect/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Ivan Bazi Architect" - short_description: "BaZi diagnosis workflow with indexed classics and guardrails." - default_prompt: "Use Ivan Bazi Architect to index the configured BaZi PDFs, run SW-1/SW-2/SW-3 diagnosis, and produce a cited, bounded strategy brief." + short_description: "Structured BaZi diagnosis with citations, uncertainty notes, and guardrails." + default_prompt: "Use Ivan Bazi Architect when the user explicitly asks for BaZi-style analysis. Build or reuse an index from configured PDFs, run SW-1/SW-2/SW-3 diagnosis, and produce a cited, bounded strategy brief." diff --git a/skills/.experimental/ivan-bazi-architect/config.example.json b/skills/.experimental/ivan-bazi-architect/config.example.json new file mode 100644 index 00000000..b970a677 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/config.example.json @@ -0,0 +1,5 @@ +{ + "source_dir": "/path/to/your/bazi-pdfs", + "output_format": "audit_memo", + "citation_mode": "book_file_snippet" +} diff --git a/skills/.experimental/ivan-bazi-architect/references/core-books.md b/skills/.experimental/ivan-bazi-architect/references/core-books.md index 2cd23a69..0d0d5481 100644 --- a/skills/.experimental/ivan-bazi-architect/references/core-books.md +++ b/skills/.experimental/ivan-bazi-architect/references/core-books.md @@ -1,8 +1,9 @@ # Core Books Map -Default source path: +Source path: -`/Users/ivan/Desktop/电子书/ddddddd/` +- Read from `config.json` (`source_dir`) or pass `--source-dir` to the index script. +- Keep user-specific local paths out of committed files. Use keyword matching because filenames may include suffixes like `(Z-Library)`, `_compressed`, uppercase `.PDF`, or author notes. diff --git a/skills/.experimental/ivan-bazi-architect/references/gotchas.md b/skills/.experimental/ivan-bazi-architect/references/gotchas.md new file mode 100644 index 00000000..edb60a93 --- /dev/null +++ b/skills/.experimental/ivan-bazi-architect/references/gotchas.md @@ -0,0 +1,24 @@ +# Gotchas + +## Trigger Boundaries + +- Use this skill only for explicit BaZi/命理 requests. +- Do not auto-apply to generic life advice, medical, legal, or financial planning prompts. + +## Citation Quality + +- Every core claim should include at least one citation from indexed sources. +- Do not cite books that are not present in the current index. +- Keep excerpts short and claim-linked. + +## Uncertainty and Language + +- Do not present outputs as deterministic fate or guaranteed outcomes. +- Prefer confidence ranges and scenario language over absolute predictions. +- Always include a boundary note in the final output. + +## Failure Patterns to Avoid + +- Skipping SW-1 and jumping directly to pattern labeling. +- Mixing incompatible flow logic without explaining conflict. +- Providing mitigation without a monitoring signal or fallback path. diff --git a/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py b/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py index adf5527a..4040a2bf 100644 --- a/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py +++ b/skills/.experimental/ivan-bazi-architect/scripts/build_pdf_index.py @@ -4,7 +4,12 @@ Example: python3 scripts/build_pdf_index.py \ - --source-dir "/Users/ivan/Desktop/电子书/ddddddd/" \ + --source-dir "/path/to/your/bazi-pdfs" \ + --out references/pdf-index.jsonl + +Or use local config fallback: + python3 scripts/build_pdf_index.py \ + --config config.json \ --out references/pdf-index.jsonl """ @@ -61,9 +66,23 @@ def read_pdf_sample(pdf_path: Path, max_pages: int, max_chars: int) -> tuple[int return page_total, sample +def read_source_dir_from_config(config_path: Path) -> str: + raw = config_path.read_text(encoding="utf-8") + data = json.loads(raw) + source_dir = data.get("source_dir") + if not isinstance(source_dir, str) or not source_dir.strip(): + raise RuntimeError(f"config missing non-empty string field 'source_dir': {config_path}") + return source_dir + + def main() -> int: parser = argparse.ArgumentParser(description="Build PDF metadata index JSONL") - parser.add_argument("--source-dir", required=True, help="Directory with source PDFs") + parser.add_argument("--source-dir", help="Directory with source PDFs") + parser.add_argument( + "--config", + default="config.json", + help="Config JSON path with source_dir fallback (default: config.json)", + ) parser.add_argument( "--out", default="references/pdf-index.jsonl", @@ -73,7 +92,19 @@ def main() -> int: parser.add_argument("--max-chars", type=int, default=6000, help="Max chars per sample") args = parser.parse_args() - source_dir = Path(args.source_dir).expanduser().resolve() + source_dir_raw = args.source_dir + if not source_dir_raw: + config_path = Path(args.config).expanduser().resolve() + if not config_path.exists(): + raise SystemExit( + f"Missing source dir. Pass --source-dir or provide config file: {config_path}" + ) + try: + source_dir_raw = read_source_dir_from_config(config_path) + except Exception as exc: + raise SystemExit(f"Failed to read source_dir from config: {exc}") from exc + + source_dir = Path(source_dir_raw).expanduser().resolve() out_path = Path(args.out).resolve() out_path.parent.mkdir(parents=True, exist_ok=True)