knowme-careerforge-skill 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -213,4 +213,8 @@ Tests use temporary directories and cover sparse/invalid facts, multiple educati
213
213
 
214
214
  Discovery metadata, activated instructions and conditional resources have separate loading costs. Keep development governance in `AGENT.md` and detailed runtime rules in `references/`. Package verification must cover dependencies and execution from outside the source checkout, separately from source-tree tests and Agent behavior evaluation.
215
215
 
216
- The current initializer has unresolved packaging and partial-success gaps; native-platform compatibility is not established by copying a prompt or passing local PDF tests. See [Agent Skills design review](docs/dev/AGENT_SKILLS_DESIGN_REVIEW.md) for evidence, target boundaries and acceptance criteria, and `AGENT.md` section 7 for maintenance rules.
216
+ The initializer now copies runtime package metadata for full bundles, reports dependency preparation separately, and returns a nonzero exit on platform failures. Source installations retain package-lock.json when available; npm archives omit it and require npm install rather than npm ci. Cursor/Windsurf adapters now point to a project-local `.knowme/skills/knowme-careerforge` bundle; Gemini configuration points to its sibling runtime bundle by absolute entrypoint. Windsurf replaces its managed block on subsequent installs. Native-platform compatibility is not established by copying a prompt or passing local PDF tests. See [Agent Skills design review](docs/dev/AGENT_SKILLS_DESIGN_REVIEW.md) for evidence, target boundaries and acceptance criteria, and `AGENT.md` section 7 for maintenance rules.
217
+
218
+ Runtime readiness is exposed by `browser-engine.js --check-runtime` (READY/UNVERIFIED); it does not certify a resume. `forge.py --summary` provides compact stdout with the canonical manifest path while retaining full on-disk diagnostics and the existing default JSON interface.
219
+
220
+ For interactive layout selection, `search-template.py --summary` exposes only the top three IDs, names, scores and layouts. Full `--json` output and the programmatic ranking interface are unchanged. Source-to-claim review in `references/01-evidence-mining.md` remains an Agent responsibility and is distinct from deterministic profile/PDF text consistency.
package/README.md CHANGED
@@ -46,7 +46,7 @@ Self Discovery Tailored Career Story
46
46
  & Evidence & Engineering Delivery
47
47
  ```
48
48
 
49
- - **KnowMe (Self-Discovery & Evidence Engine)**: Helps candidates discover who they are, uncover their verifiable career evidence (L1~L3), and map their true competitive strengths.
49
+ - **KnowMe (Self-Discovery & Evidence Engine)**: Helps candidates discover who they are, organize their supplied career experience and supporting material, and map their true competitive strengths.
50
50
  - **CareerForge (Career Positioning & Resume Engineering)**: Translates genuine strengths into targeted positioning for specific job opportunities, tailoring high-impact content inside an **HTML Intermediate Working Canvas** with **Design Tokens**, and delivering deterministic, pixel-perfect PDFs via Playwright.
51
51
 
52
52
  ---
@@ -97,21 +97,24 @@ knowme list
97
97
 
98
98
  ---
99
99
 
100
- ### Option B: Direct Agent Integration
100
+ ### Platform entrypoints and runtime resources
101
101
 
102
- | Platform | Target Configuration Path | Setup Command |
103
- | :--- | :--- | :--- |
104
- | **Cursor** | `.cursor/rules/knowme-careerforge.mdc` | `cp SKILL.md .cursor/rules/knowme-careerforge.mdc` |
105
- | **Claude Code** | `~/.claude/skills/knowme-careerforge/` | `cp -r knowme-careerforge-skill ~/.claude/skills/` |
106
- | **Codex** | `~/.codex/skills/knowme-careerforge/` | `cp -r knowme-careerforge-skill ~/.codex/skills/` |
107
- | **Windsurf** | `.windsurfrules` | `cat agents/windsurf/knowme-careerforge.rules >> .windsurfrules` |
108
- | **OpenCode** | `.opencode/skills/knowme-careerforge/` | `cp -r knowme-careerforge-skill ~/.opencode/skills/` |
102
+ | Platform | Entry location | Configuration command |
103
+ | --- | --- | --- |
104
+ | Claude Code | `~/.claude/skills/knowme-careerforge/SKILL.md` | `knowme init --ai claude` |
105
+ | Codex | `~/.codex/skills/knowme-careerforge/SKILL.md` | `knowme init --ai codex` |
106
+ | Cursor | `.cursor/rules/knowme-careerforge.mdc` | `knowme init --ai cursor` |
107
+ | Windsurf | Managed block in `.windsurfrules` | `knowme init --ai windsurf` |
108
+ | Gemini | `~/.gemini/skills/knowme-careerforge.json` | `knowme init --ai gemini` |
109
+ | OpenCode | `.opencode/skills/knowme-careerforge/SKILL.md` | `knowme init --ai opencode` |
110
+
111
+ Cursor/Windsurf reference a project-local `.knowme/skills/knowme-careerforge/` runtime; Gemini configuration points to its sibling runtime directory. Each routes to the same SKILL.md workflow. File installation does not certify host discovery or behavior. Copying a prompt alone is insufficient. Rerun init after relocating an installation to refresh entry paths.
109
112
 
110
113
  ---
111
114
 
112
115
  ## 4. User input and artifact lifecycle
113
116
 
114
- The host Agent organizes user descriptions, existing resume material and explicitly supplied supporting evidence. Repository-to-resume extraction is not supported. A target role is sufficient; a JD is optional.
117
+ The host Agent organizes user descriptions, existing resume material and explicitly supplied supporting evidence. Repository-to-resume extraction is not supported. A target role starts intake; a JD is optional. Without candidate material, ask and wait rather than generating an example.
115
118
 
116
119
  Draft retains incomplete information, Master preserves supplied facts, and Variant records its source Master hash for a target role. Missing values stay omitted/null; sample people, default honors and invented metrics never fill gaps. See the [artifact and acceptance contract](references/07-artifact-contract.md).
117
120
 
@@ -121,7 +124,7 @@ Each forge invocation writes snapshots, Master, Variant, canvas, QA and manifest
121
124
 
122
125
  Checks run in print mode across every page, then parse the final PDF's page dimensions and extracted text. PASS means current checks passed; FAIL means a check failed; UNVERIFIED means inspection could not complete; DRAFT means draft preparation only. Automated checks do not certify factual truth or every ATS.
123
126
 
124
- Requires Python 3.9+, Node.js 22.13+, npm runtime dependencies and Chromium. Run `npm install`; use `npx playwright install chromium` if no system Chromium is available.
127
+ Prepare dependencies in the installed runtime as instructed by init (`npm ci --omit=dev` with a lockfile, otherwise `npm install --omit=dev`), then run `node scripts/rendering/browser-engine.js --check-runtime`. Python 3.9+, Node.js 22.13+ and Chromium are required. READY is runtime readiness, not resume acceptance. Deliver one current PDF and editable HTML by default; `forge.py --summary` keeps stdout concise while retaining internal snapshots and diagnostics.
125
128
 
126
129
  ---
127
130
 
package/README.zh-CN.md CHANGED
@@ -46,7 +46,7 @@ knowme-careerforge-skill
46
46
  真实经历与证据 工程化定制交付
47
47
  ```
48
48
 
49
- - **KnowMe(自我认知与证据挖掘引擎)**:帮助候选人深入认知自我,系统梳理真实经历与可验证的代码/项目证据(L1~L3 分级),提炼真正具备竞争壁垒的优势点。
49
+ - **KnowMe(自我认知与证据挖掘引擎)**:帮助候选人深入认知自我,系统梳理用户提供的真实经历与辅助材料,提炼真正具备竞争壁垒的优势点。
50
50
  - **CareerForge(职业定位与简历工程引擎)**:将候选人的真实优势精准对齐目标岗位(JD),以 **HTML 中间工作区(Intermediate Canvas)** 与 **Design Tokens(设计系统变量)** 为工作场进行微调排版,最终通过 Playwright 无头浏览器导出确定性、像素级的矢量 PDF。
51
51
 
52
52
  ---
@@ -99,21 +99,24 @@ knowme list
99
99
 
100
100
  ---
101
101
 
102
- ### 方式 B:Agent 平台原生手动配置
102
+ ### 平台入口与运行资源
103
103
 
104
- | 平台 | 目标注入路径 | 配置方法 |
105
- | :--- | :--- | :--- |
106
- | **Cursor** | `.cursor/rules/knowme-careerforge.mdc` | `cp SKILL.md .cursor/rules/knowme-careerforge.mdc` |
107
- | **Claude Code** | `~/.claude/skills/knowme-careerforge/` | `cp -r knowme-careerforge-skill ~/.claude/skills/` |
108
- | **Codex** | `~/.codex/skills/knowme-careerforge/` | `cp -r knowme-careerforge-skill ~/.codex/skills/` |
109
- | **Windsurf** | `.windsurfrules` | `cat agents/windsurf/knowme-careerforge.rules >> .windsurfrules` |
110
- | **OpenCode** | `.opencode/skills/knowme-careerforge/` | `cp -r knowme-careerforge-skill ~/.opencode/skills/` |
104
+ | 平台 | 入口位置 | 配置命令 |
105
+ | --- | --- | --- |
106
+ | Claude Code | `~/.claude/skills/knowme-careerforge/SKILL.md` | `knowme init --ai claude` |
107
+ | Codex | `~/.codex/skills/knowme-careerforge/SKILL.md` | `knowme init --ai codex` |
108
+ | Cursor | `.cursor/rules/knowme-careerforge.mdc` | `knowme init --ai cursor` |
109
+ | Windsurf | `.windsurfrules` 的托管块 | `knowme init --ai windsurf` |
110
+ | Gemini | `~/.gemini/skills/knowme-careerforge.json` | `knowme init --ai gemini` |
111
+ | OpenCode | `.opencode/skills/knowme-careerforge/SKILL.md` | `knowme init --ai opencode` |
112
+
113
+ Cursor/Windsurf 的运行资源位于项目 `.knowme/skills/knowme-careerforge/`,配置中写入准确入口;Gemini 配置指向同级运行目录。所有入口引用同一个 SKILL.md 工作流。安装完成表示文件已准备,宿主发现与实际行为需分别验证;不应只复制提示文件就认为工具可运行。移动安装目录后重新运行 init 更新路径。
111
114
 
112
115
  ---
113
116
 
114
117
  ## 4. 用户信息与资料生命周期
115
118
 
116
- 当前功能依靠用户描述、已有简历和明确提供的支持材料,由宿主 Agent 组织与定制内容;不支持代码仓库分析回填。目标岗位即可开始,JD 可选。
119
+ 当前功能依靠用户描述、已有简历和明确提供的支持材料,由宿主 Agent 组织与定制内容;不支持代码仓库分析回填。目标岗位即可开始收集资料,JD 可选;没有候选人材料时先提问并等待,不生成演示履历。
117
120
 
118
121
  Draft 保留不完整资料,Master 保存本次已知事实,Variant 记录来源 Master 的摘要并派生岗位表达。缺失值省略或 null,不补示例姓名、默认荣誉和任意指标。完整规则见 [资料与验收契约](references/07-artifact-contract.md)。
119
122
 
@@ -123,7 +126,7 @@ Draft 保留不完整资料,Master 保存本次已知事实,Variant 记录
123
126
 
124
127
  打印模式会检查所有页面,再解析最终 PDF 的每页尺寸与文本。PASS 表示本次检查通过;FAIL 是检查失败;UNVERIFIED 是浏览器/依赖等导致无法验收;DRAFT 只表示草稿准备完成。自动检查不等同于事实核实或通用 ATS 认证。
125
128
 
126
- 需要 Python 3.9+、Node.js 22.13+ 和 npm 运行依赖。运行 `npm install`;没有系统 Chromium 时使用 `npx playwright install chromium`。
129
+ 在安装目录按 init 提示准备依赖(有锁文件时 `npm ci --omit=dev`,否则 `npm install --omit=dev`),再运行 `node scripts/rendering/browser-engine.js --check-runtime`。需要 Python 3.9+、Node.js 22.13+ 与可用 Chromium。运行预检 READY 不表示简历已验收。默认只交付一个版本的 PDF 和可编辑 HTML;`forge.py --summary` 精简终端输出,内部快照与诊断仍保留。
127
130
 
128
131
  ---
129
132
 
package/SKILL.md CHANGED
@@ -4,46 +4,68 @@ description: Create or refine a tailored resume from user descriptions, existing
4
4
  license: MIT
5
5
  compatibility: Requires Python 3.9+, Node.js 22.13+, the npm dependencies declared by this project, and Chromium for print/PDF checks. Explicit local font presets require the named font.
6
6
  metadata:
7
- version: 0.0.6
7
+ version: 0.0.7
8
8
  ---
9
9
 
10
10
  # KnowMe CareerForge
11
11
 
12
- Use the user's descriptions, existing resume and supplied supporting material. The host Agent understands, selects and rewrites content. Repository mining and automatic repo-to-resume backfill are not supported input paths. Do not scan the current project to infer candidate facts.
12
+ Create a readable resume from the user's descriptions, existing resume and explicitly supplied material. The host Agent selects and rewrites facts; tools bind templates and check printing. Repository mining and automatic repo-to-resume backfill are not supported. Development tasks use AGENT.md; making a resume does not require reading development docs or tool source code.
13
13
 
14
- Reuse information already given and ask only useful follow-up questions. A target role is enough; a JD is optional. Make progress with sparse information when the user wants a draft. Do not impose a complete questionnaire or invent facts to fill empty fields. Preserve explicit user choices of language, template, page count and requested edit.
14
+ ## 1. Start from the conversation
15
15
 
16
- Keep employers, dates, degrees, responsibilities, metrics and ownership faithful to the input. User statements are supplied facts; do not downgrade “led” to “participated” merely because the source is chat. Do not claim independent verification without doing it. Keep gaps and uncertainties outside the resume rather than writing invented placeholder achievements.
16
+ Reuse information already given. A target role is sufficient to start the conversation, not to invent a candidate. A JD is optional. Decide whether candidate material exists before reading references, inspecting templates or checking runtime. With no material, a sufficient first response is: “请发已有简历,或告诉我姓名、最近一段工作经历(公司、时间、做了什么、用过哪些技术);已有的信息不用重复。”
17
17
 
18
- For help developing or reviewing this Skill repository, use its development documentation; do not start a candidate intake or resume-generation workflow merely because the repository contains resume tools.
18
+ - **Only a role, no candidate material:** ask for an existing resume or a short description of recent work, dates and technologies. Then wait. Do not build sample resumes, inspect every reference, or create test profiles while awaiting an answer. If a host task list is used, mark intake as awaiting input using the host’s supported state; drafting and rendering depend on it and remain pending. A TODO reminder does not unlock them. Do not create a task list just to run this simple workflow.
19
+ - **Usable facts supplied:** organize them directly. Missing optional contact, school or date fields do not require a Draft detour. Ask only consequential follow-ups; proceed with known facts when the user wants a result. If experience is known but the name is missing, ask just for the name needed for PDF delivery, or prepare an unnamed Draft if requested.
20
+ - **Draft requested or delivery input insufficient:** use `--draft` for an explicitly requested partial canvas. Label it DRAFT; do not promise a verified PDF.
21
+ - **Existing canvas edited:** preserve those edits and validate/render that canvas to a new revision path; do not overwrite it from an older profile.
19
22
 
20
- ## Preserve the artifact lifecycle
23
+ Preserve employers, dates, qualifications, metrics and ownership exactly in meaning. “Participated” cannot become “led”; a target Java role does not prove Java experience. Role knowledge and JD keywords are prompts for questions, never evidence of skills. Do not add common tools, proficiency, implementation mechanisms, projects or outcomes merely because they sound plausible. Gallery `sample-profile.json` is fictional and never candidate input. If a user explicitly requests a fictional example, label it separately and keep it out of their fact record.
21
24
 
22
- Read [the shared artifact and error contract](references/07-artifact-contract.md) before running the pipeline. Draft, Master and Variant describe different artifacts. They do not mean the same thing as PASS, FAIL or UNVERIFIED.
25
+ ## 2. Compose once, choose a layout
23
26
 
24
- - Prepare a Draft when information is incomplete. Unknown optional values are omitted or null, never sample candidate text.
25
- - Keep the user's facts in a Master; derive a Variant for a target role without overwriting the original facts. User-provided plain profile JSON remains supported. Users do not need to author JSON themselves.
26
- - Use an isolated run directory for each pipeline invocation. Read the returned manifest and exact output paths; never infer success from an existing workspace/resume.pdf.
27
- - When editing an existing canvas, preserve those edits and validate/render that canvas. Do not regenerate from an older profile and overwrite later content edits. Write a new output path for a new revision.
27
+ Before composing, read [the source-to-claim rules](references/01-evidence-mining.md) once and check the rewritten claims against the original user material. Comparing a generated profile with its own PDF does not check factual fidelity. Keep a single editable profile of supplied facts. Read [the artifact contract](references/07-artifact-contract.md) for its short input example and lifecycle. The pipeline creates Master/Variant snapshots; the user need not write JSON or receive every snapshot. Master means this run's known facts, not that every optional field is complete.
28
28
 
29
- Resolve scripts and resources relative to this SKILL.md, regardless of current directory. Write candidate artifacts in the user's workspace. Tools require Python 3.9+, Node.js 22.13+ and installed npm runtime dependencies. Printing requires system Chromium or Playwright Chromium. Missing runtime means UNVERIFIED, not PASS.
29
+ Write short, concrete bullets. A useful default is a brief optional summary, compact skill groups, and evidence in work/project entries. Do not repeat the same achievement in summary, work and an invented project. A project section is optional: add one only when supplied project detail adds something distinct. Metrics and technical mechanisms appear only when supplied; duties without metrics remain valid. Follow the user's requested level of detail.
30
+
31
+ Read [template guidance](references/04-template-selection.md) when choosing a template. Honor an explicit choice; otherwise choose for actual content length and hierarchy, or omit `--template` for ranked selection. Do not hardcode minimal because the role is backend. State the actual `templateUsed` in delivery. Each template has one structural source, `canvas.html`; previews bind fictional data through the same renderer.
32
+
33
+ ## 3. Prepare runtime, generate
34
+
35
+ Use the absolute SKILL.md path already returned by the host to resolve `<skill-root>`. The model name does not determine the installation directory: a Gemini model may be running through a host that resolves `.claude/skills`. If unavailable, inspect the host's configured skill location; do not recursively search the home directory. Candidate files belong in the user's workspace, never the installation directory.
36
+
37
+ After there is sufficient candidate material, and before the first PDF build, run:
30
38
 
31
39
  ```bash
32
- # Assemble and verify Agent-prepared user facts in an isolated run directory.
33
- python3 <skill-root>/scripts/pipeline/forge.py --profile-json <master.json> --role "<target role>" --template minimal --quiet
40
+ node <skill-root>/scripts/rendering/browser-engine.js --check-runtime
41
+ ```
42
+
43
+ READY only checks runtime availability, not resume quality. If unavailable, use its diagnostics and the installed package.json to prepare dependencies once under the host's permission rules. With a lockfile use `npm ci --omit=dev`; otherwise use `npm install --omit=dev`, in `<skill-root>`. Do not guess and install packages one error at a time. If package.json or required bundled scripts are absent, the installation is incomplete: repair it from the project package rather than synthesizing a manifest or installing guessed dependencies. Chromium is also required. If setup is blocked, report UNVERIFIED and offer a requested Draft; do not repeatedly run the full pipeline unchanged.
34
44
 
35
- # Incomplete input: return a draft, without a verified PDF claim.
36
- python3 <skill-root>/scripts/pipeline/forge.py --profile-json <draft.json> --draft --quiet
45
+ For a new resume, keep internal files under `workspace/` and publish only the readable deliverables under `resume/` (or the user's chosen locations):
37
46
 
38
- # Validate an existing edited canvas; export rechecks the final PDF.
39
- python3 <skill-root>/scripts/validation/validate-resume.py <resume.html> --expected-pages 1 --json
40
- python3 <skill-root>/scripts/rendering/render-pdf.py <resume.html> <new-resume.pdf> --expected-pages 1 --quiet
47
+ ```bash
48
+ python3 <skill-root>/scripts/pipeline/forge.py --profile-json workspace/profile.json --workspace workspace/runs --role "<target role>" --output resume/resume.pdf --html-output resume/resume.html --summary
41
49
  ```
42
50
 
43
- ## Assemble and inspect
51
+ Add `--template <chosen-id>` for an explicit layout. Drafts use `--draft` without PDF/copy flags; return the exact HTML path reported. Each invocation isolates its artifacts. A successful preflight need not be repeated on contact or wording updates unless the environment changes. Read the returned status and paths; never guess `workspace/resume.pdf` or treat a previous copy as this run's success. Full diagnostics remain in the returned manifest; open them only when needed. Fix a reported cause before retrying.
52
+
53
+ For existing edited HTML:
54
+
55
+ ```bash
56
+ python3 <skill-root>/scripts/rendering/render-pdf.py <edited-resume.html> <new-resume.pdf> --expected-pages 1 --quiet
57
+ ```
58
+
59
+ ## 4. Inspect and deliver
60
+
61
+ Check rewritten content against the user's input before rendering. After tool acceptance, inspect the final PDF visually on every page: hierarchy, small type, excessive whitespace, dense skills, duplication and education/date alignment. An HTML screenshot or PDF file size does not prove final PDF appearance. If visual tools are unavailable, disclose that limitation. After an accepted result and the completed visual/content review, stop. Do not perform another identical export, measure file size as extra QA, or create another named copy. Read [canvas tuning](references/05-html-canvas-tokens.md) only for layout edits and [QA diagnostics](references/06-qa-and-rendering.md) for failures.
62
+
63
+ PASS requires this PDF's page, text and layout checks. It does not certify truth, persuasive design or universal ATS compatibility. Do not shrink sparse resumes, fabricate content to fill the page, silently remove facts, or relax checks to pass. Preserve failures for diagnosis; do not delete run history as cosmetic cleanup. Font extraction failures require inspecting diagnostics and an available font choice, not altering candidate text.
64
+
65
+ Default delivery: link PDF and editable HTML, name the template, and briefly note useful remaining gaps. Do not repeat the entire resume, dump QA tables, or link input/Master/Variant/manifest unless requested or needed to explain failure. FAIL/UNVERIFIED must identify the concrete blocker; DRAFT must remain clearly labeled.
44
66
 
45
- Use `canvas.html` as the sole maintained template structure. Gallery previews bind explicit `sample-profile.json` through the same instantiator; never use gallery samples as candidate facts. All education, work and project entries are independent. Treat an injection error as failure; never deliver the untouched sample template. For template choice and token tuning, read [template guidance](references/04-template-selection.md) and [canvas guidance](references/05-html-canvas-tokens.md).
67
+ Use one concise delivery shape across hosts, adapting only language and filenames:
46
68
 
47
- Check facts against the input, inspect print layout and run [QA and rendering](references/06-qa-and-rendering.md). Automatic tuning may reduce spacing and font sizes within limits, but cannot replace content review. When fitting fails, adjust expression, select another layout or use the user's allowed page count. Do not silently delete facts. If PDF extraction reports font mapping differences, inspect missingCodepoints and extractedRadicals; an explicit available font preset such as `--font-preset arial-unicode` can be used in a new run. Never relax text checks or rewrite candidate facts to bypass a font failure.
69
+ > 已生成简历: [PDF](<current PDF path>) · [可编辑 HTML](<current HTML path>)。模板:<templateUsed>。<One useful gap or actual inspection limitation, if any.>
48
70
 
49
- Report the actual result concisely with the produced file paths. PASS requires the current PDF's page, text and layout checks. FAIL or UNVERIFIED must explain the concrete error; DRAFT must be labeled as a draft. Basic PDF text checks are not universal ATS certification.
71
+ Return one current version by default, not several template alternatives or separate analysis reports. For an update, patch only the requested fields in the current working profile/canvas, retain the selected template and public filenames unless the user asks to change them, and publish the newly accepted revision; keep previous runs internal. When blocked, give the blocker and the single next action instead of a success-shaped delivery. Keep progress updates about observable work, not a running commentary of every file read or schema decision.
@@ -1,3 +1,3 @@
1
1
  # KnowMe CareerForge
2
2
 
3
- Read the installed SKILL.md and references/07-artifact-contract.md. Use user-supplied facts, preserve Draft/Master/Variant separation and write each pipeline run into its own directory. Repository mining is not supported. Only the current PASS manifest identifies verified PDF delivery; never substitute an old workspace file after failure.
3
+ Read SKILL.md at the installed skill root and follow it as the single runtime workflow. Resolve its scripts and references from that directory, not the candidate workspace. Load supporting references only when the current step needs them. Do not load AGENT.md or architecture documents to make a resume.
@@ -1,22 +1,6 @@
1
1
  name: knowme-careerforge
2
2
  description: An agent-native skill for self-discovery, career positioning, and tailored resume engineering.
3
- version: 0.0.6
3
+ version: 0.0.7
4
4
  entrypoint: SKILL.md
5
- tools:
6
- - name: forge
7
- command: python3 scripts/pipeline/forge.py
8
- - name: search-template
9
- command: python3 scripts/template/search-template.py
10
- - name: analyze-jd
11
- command: python3 scripts/evidence/analyze-jd.py
12
- - name: instantiate-resume
13
- command: python3 scripts/template/instantiate-resume.py
14
- - name: validate-resume
15
- command: python3 scripts/validation/validate-resume.py
16
- - name: render-pdf
17
- command: python3 scripts/rendering/render-pdf.py
18
5
  rules:
19
- - "Execute tools silently in background with --quiet (DO NOT print raw HTML, full CSS, or scripts in chat)."
20
- - "Use the current isolated run canvas and preserve Master/Variant lineage."
21
- - "Deliver only the current PASS manifest outputs; report DRAFT, FAIL and UNVERIFIED accurately."
22
- - "Reference AGENT.md, ARCHITECTURE.md, and references/01~06 for complete specifications."
6
+ - "Read SKILL.md at the installed skill root and follow it as the single runtime workflow. Resolve its scripts and references from that directory, not the candidate workspace. Load supporting references only when the current step needs them. Do not load AGENT.md or architecture documents to make a resume."
@@ -5,4 +5,4 @@ alwaysApply: false
5
5
 
6
6
  # KnowMe CareerForge
7
7
 
8
- Read the installed SKILL.md and references/07-artifact-contract.md. Use user-supplied facts, preserve Draft/Master/Variant separation and write each pipeline run into its own directory. Repository mining is not supported. Only the current PASS manifest identifies verified PDF delivery; never substitute an old workspace file after failure.
8
+ Read SKILL.md at the installed skill root and follow it as the single runtime workflow. Resolve its scripts and references from that directory, not the candidate workspace. Load supporting references only when the current step needs them. Do not load AGENT.md or architecture documents to make a resume.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knowme-careerforge",
3
3
  "description": "An agent-native skill for self-discovery, career positioning, and tailored resume engineering.",
4
- "instructions": "Execute the 6-stage KnowMe CareerForge workflow: Know Me (L1~L3 evidence) -> Define -> Understand (JD signals) -> Position -> Forge (HTML canvas & tokens) -> Review (Dual QA & PDF export).",
4
+ "instructions": "Read SKILL.md at the installed skill root and follow it as the single runtime workflow. Resolve its scripts and references from that directory, not the candidate workspace. Load supporting references only when the current step needs them. Do not load AGENT.md or architecture documents to make a resume.",
5
5
  "entrypoint": "SKILL.md"
6
6
  }
@@ -1,7 +1,7 @@
1
1
  name: knowme-careerforge
2
2
  displayName: KnowMe CareerForge
3
3
  description: An agent-native skill for self-discovery, career positioning, and tailored resume engineering.
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  schema: 1.0
6
6
  entrypoint: SKILL.md
7
7
  tags:
@@ -1,3 +1,3 @@
1
1
  # KnowMe CareerForge
2
2
 
3
- Read the installed SKILL.md and references/07-artifact-contract.md. Use user-supplied facts, preserve Draft/Master/Variant separation and write each pipeline run into its own directory. Repository mining is not supported. Only the current PASS manifest identifies verified PDF delivery; never substitute an old workspace file after failure.
3
+ Read SKILL.md at the installed skill root and follow it as the single runtime workflow. Resolve its scripts and references from that directory, not the candidate workspace. Load supporting references only when the current step needs them. Do not load AGENT.md or architecture documents to make a resume.
@@ -70,6 +70,25 @@ function copyDirRecursive(src, dest) {
70
70
  }
71
71
  }
72
72
  }
73
+ function copyRuntimeBundle(rootDir, destination) {
74
+ fs.mkdirSync(destination, { recursive: true });
75
+ for (const directory of ['scripts', 'src', 'references']) {
76
+ copyDirRecursive(path.join(rootDir, directory), path.join(destination, directory));
77
+ }
78
+ for (const file of ['SKILL.md', 'skill.json', 'package.json']) {
79
+ fs.copyFileSync(path.join(rootDir, file), path.join(destination, file));
80
+ }
81
+ // npm archives omit package-lock.json; source checkouts can retain a locked install.
82
+ const lock = path.join(rootDir, 'package-lock.json');
83
+ const installedLock = path.join(destination, 'package-lock.json');
84
+ if (fs.existsSync(lock))
85
+ fs.copyFileSync(lock, installedLock);
86
+ else
87
+ fs.rmSync(installedLock, { force: true });
88
+ console.log(`Runtime files copied -> ${destination}`);
89
+ console.log(`Prepare dependencies in that directory: npm ${fs.existsSync(lock) ? 'ci' : 'install'} --omit=dev`);
90
+ console.log('Then run: node scripts/rendering/browser-engine.js --check-runtime');
91
+ }
73
92
  function runInit(options) {
74
93
  const rootDir = findPackageRoot(__dirname);
75
94
  const projectDir = options.projectDir ? path.resolve(options.projectDir) : process.cwd();
@@ -85,82 +104,82 @@ function runInit(options) {
85
104
  console.log(` Target Project: ${projectDir}`);
86
105
  console.log(` Platforms : ${targetPlatforms.join(', ')}`);
87
106
  console.log('==============================================================');
107
+ let failures = 0;
88
108
  for (const plat of targetPlatforms) {
89
109
  try {
90
110
  switch (plat) {
91
111
  case 'claude': {
92
112
  const claudeDir = path.join(homeDir, '.claude', 'skills', 'knowme-careerforge');
93
- fs.mkdirSync(claudeDir, { recursive: true });
94
- copyDirRecursive(path.join(rootDir, 'scripts'), path.join(claudeDir, 'scripts'));
95
- copyDirRecursive(path.join(rootDir, 'src'), path.join(claudeDir, 'src'));
96
- copyDirRecursive(path.join(rootDir, 'references'), path.join(claudeDir, 'references'));
97
- fs.copyFileSync(path.join(rootDir, 'SKILL.md'), path.join(claudeDir, 'SKILL.md'));
98
- fs.copyFileSync(path.join(rootDir, 'AGENT.md'), path.join(claudeDir, 'AGENT.md'));
99
- fs.copyFileSync(path.join(rootDir, 'ARCHITECTURE.md'), path.join(claudeDir, 'ARCHITECTURE.md'));
100
- fs.copyFileSync(path.join(rootDir, 'skill.json'), path.join(claudeDir, 'skill.json'));
101
- console.log(`[✓] Claude Code Skill fully bundled -> ${claudeDir}`);
113
+ copyRuntimeBundle(rootDir, claudeDir);
114
+ console.log(`[✓] Claude Code Skill files installed -> ${claudeDir}`);
102
115
  break;
103
116
  }
104
117
  case 'codex': {
105
118
  const codexDir = path.join(homeDir, '.codex', 'skills', 'knowme-careerforge');
106
- fs.mkdirSync(codexDir, { recursive: true });
107
- copyDirRecursive(path.join(rootDir, 'scripts'), path.join(codexDir, 'scripts'));
108
- copyDirRecursive(path.join(rootDir, 'src'), path.join(codexDir, 'src'));
109
- copyDirRecursive(path.join(rootDir, 'references'), path.join(codexDir, 'references'));
110
- fs.copyFileSync(path.join(rootDir, 'SKILL.md'), path.join(codexDir, 'SKILL.md'));
111
- fs.copyFileSync(path.join(rootDir, 'AGENT.md'), path.join(codexDir, 'AGENT.md'));
112
- fs.copyFileSync(path.join(rootDir, 'ARCHITECTURE.md'), path.join(codexDir, 'ARCHITECTURE.md'));
113
- fs.copyFileSync(path.join(rootDir, 'skill.json'), path.join(codexDir, 'skill.json'));
119
+ copyRuntimeBundle(rootDir, codexDir);
114
120
  if (fs.existsSync(path.join(rootDir, 'agents', 'codex', 'knowme-careerforge.yaml'))) {
115
121
  fs.copyFileSync(path.join(rootDir, 'agents', 'codex', 'knowme-careerforge.yaml'), path.join(codexDir, 'skill.yaml'));
116
122
  }
117
- console.log(`[✓] Codex Native Skill fully bundled -> ${codexDir}`);
123
+ console.log(`[✓] Codex Native Skill files installed -> ${codexDir}`);
118
124
  break;
119
125
  }
120
126
  case 'cursor': {
121
127
  const cursorRulesDir = path.join(projectDir, '.cursor', 'rules');
122
128
  fs.mkdirSync(cursorRulesDir, { recursive: true });
129
+ const runtimeDir = path.join(projectDir, '.knowme', 'skills', 'knowme-careerforge');
130
+ copyRuntimeBundle(rootDir, runtimeDir);
123
131
  const mdcContent = fs.readFileSync(path.join(rootDir, 'agents', 'cursor', 'knowme-careerforge.mdc'), 'utf-8');
124
- fs.writeFileSync(path.join(cursorRulesDir, 'knowme-careerforge.mdc'), mdcContent, 'utf-8');
132
+ fs.writeFileSync(path.join(cursorRulesDir, 'knowme-careerforge.mdc'), mdcContent + `\nRuntime entry: ${JSON.stringify(path.join(runtimeDir, 'SKILL.md'))}\n`, 'utf-8');
125
133
  console.log(`[✓] Cursor MDC Rule configured -> ${path.join(cursorRulesDir, 'knowme-careerforge.mdc')}`);
126
134
  break;
127
135
  }
128
136
  case 'windsurf': {
129
137
  const windsurfRulePath = path.join(projectDir, '.windsurfrules');
138
+ const runtimeDir = path.join(projectDir, '.knowme', 'skills', 'knowme-careerforge');
139
+ copyRuntimeBundle(rootDir, runtimeDir);
130
140
  const ruleContent = fs.readFileSync(path.join(rootDir, 'agents', 'windsurf', 'knowme-careerforge.rules'), 'utf-8');
131
- fs.appendFileSync(windsurfRulePath, `\n\n${ruleContent}`, 'utf-8');
141
+ const begin = '<!-- knowme-careerforge:start -->';
142
+ const end = '<!-- knowme-careerforge:end -->';
143
+ const previous = fs.existsSync(windsurfRulePath) ? fs.readFileSync(windsurfRulePath, 'utf-8') : '';
144
+ const block = `${begin}\n${ruleContent}\nRuntime entry: ${JSON.stringify(path.join(runtimeDir, 'SKILL.md'))}\n${end}`;
145
+ const managed = /<!-- knowme-careerforge:start -->[\s\S]*?<!-- knowme-careerforge:end -->/;
146
+ fs.writeFileSync(windsurfRulePath, managed.test(previous) ? previous.replace(managed, () => block) : previous + `\n\n${block}\n`, 'utf-8');
132
147
  console.log(`[✓] Windsurf Rule configured -> ${windsurfRulePath}`);
133
148
  break;
134
149
  }
135
150
  case 'gemini': {
136
151
  const geminiDir = path.join(homeDir, '.gemini', 'skills');
137
152
  fs.mkdirSync(geminiDir, { recursive: true });
138
- const geminiJson = fs.readFileSync(path.join(rootDir, 'agents', 'gemini', 'knowme-careerforge.json'), 'utf-8');
139
- fs.writeFileSync(path.join(geminiDir, 'knowme-careerforge.json'), geminiJson, 'utf-8');
153
+ const runtimeDir = path.join(geminiDir, 'knowme-careerforge');
154
+ copyRuntimeBundle(rootDir, runtimeDir);
155
+ const geminiConfig = JSON.parse(fs.readFileSync(path.join(rootDir, 'agents', 'gemini', 'knowme-careerforge.json'), 'utf-8'));
156
+ geminiConfig.entrypoint = path.join(runtimeDir, 'SKILL.md');
157
+ fs.writeFileSync(path.join(geminiDir, 'knowme-careerforge.json'), JSON.stringify(geminiConfig, null, 2) + '\n', 'utf-8');
140
158
  console.log(`[✓] Gemini CLI Skill configured -> ${path.join(geminiDir, 'knowme-careerforge.json')}`);
141
159
  break;
142
160
  }
143
161
  case 'opencode': {
144
162
  const opencodeDir = path.join(projectDir, '.opencode', 'skills', 'knowme-careerforge');
145
- fs.mkdirSync(opencodeDir, { recursive: true });
146
- copyDirRecursive(path.join(rootDir, 'scripts'), path.join(opencodeDir, 'scripts'));
147
- copyDirRecursive(path.join(rootDir, 'src'), path.join(opencodeDir, 'src'));
148
- copyDirRecursive(path.join(rootDir, 'references'), path.join(opencodeDir, 'references'));
149
- fs.copyFileSync(path.join(rootDir, 'SKILL.md'), path.join(opencodeDir, 'SKILL.md'));
150
- fs.copyFileSync(path.join(rootDir, 'AGENT.md'), path.join(opencodeDir, 'AGENT.md'));
151
- fs.copyFileSync(path.join(rootDir, 'ARCHITECTURE.md'), path.join(opencodeDir, 'ARCHITECTURE.md'));
152
- fs.copyFileSync(path.join(rootDir, 'skill.json'), path.join(opencodeDir, 'skill.json'));
153
- console.log(`[✓] OpenCode Skill fully bundled -> ${opencodeDir}`);
163
+ copyRuntimeBundle(rootDir, opencodeDir);
164
+ console.log(`[✓] OpenCode Skill files installed -> ${opencodeDir}`);
154
165
  break;
155
166
  }
156
167
  default:
168
+ failures += 1;
157
169
  console.log(`[!] Unknown platform: ${plat}. Supported: ${SUPPORTED_PLATFORMS.join(', ')}`);
158
170
  }
159
171
  }
160
172
  catch (err) {
173
+ failures += 1;
161
174
  const msg = err instanceof Error ? err.message : String(err);
162
175
  console.error(`[✗] Failed to initialize ${plat}: ${msg}`);
163
176
  }
164
177
  }
165
- console.log('\n[✓] Skill setup complete. You can now use knowme-careerforge in your agent workflows!');
178
+ if (failures) {
179
+ process.exitCode = 1;
180
+ console.error(`[✗] ${failures} platform setup(s) failed.`);
181
+ }
182
+ else {
183
+ console.log('Configuration and runtime files installed. Prepare dependencies and check runtime before generating PDFs; host discovery must be verified separately.');
184
+ }
166
185
  }
@@ -58,11 +58,11 @@ function getVersion(rootDir) {
58
58
  const pkgJson = path.join(rootDir, 'package.json');
59
59
  if (require('fs').existsSync(pkgJson)) {
60
60
  const data = JSON.parse(require('fs').readFileSync(pkgJson, 'utf-8'));
61
- return data.version || '0.0.6';
61
+ return data.version || '0.0.7';
62
62
  }
63
63
  }
64
64
  catch { }
65
- return '0.0.6';
65
+ return '0.0.7';
66
66
  }
67
67
  function showHelp() {
68
68
  console.log(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knowme-careerforge-skill",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "An agent-native skill for self-discovery, career positioning, and tailored resume engineering.",
5
5
  "main": "dist/cli/src/index.js",
6
6
  "bin": {
@@ -1,5 +1,35 @@
1
- # Organize user-supplied facts
1
+ # Turn supplied facts into resume claims
2
2
 
3
- Use the user's descriptions, prior resume and explicitly supplied supporting material. Repository scanning is not a supported candidate input mode. Reuse known information; ask progressive follow-up questions only for consequential gaps. Do not invent dates, employers, degrees or metrics, or weaken stated ownership solely because it came from chat.
3
+ Read this when composing or materially rewriting candidate content. Compare with the user's original messages or supplied resume, not just an Agent-generated profile. Tools verify that profile text survives rendering; they cannot establish that the profile was faithful in the first place.
4
4
 
5
- Store incomplete information as Draft and reviewed supplied facts as Master. Derive role-specific Variant content without changing the Master. Unknown values remain omitted/null. Follow the shared lifecycle and error rules in 07-artifact-contract.md.
5
+ ## Compose, then check against the source
6
+
7
+ 1. Identify supplied facts and the target role separately. Treat role/JD knowledge as requirements to compare, not personal qualifications. Do not read role profiles for a straightforward rewrite; consult them only for a specific positioning question.
8
+ 2. Write a concise draft of the content. Every skill, responsibility, mechanism, result and level of proficiency must be supported by supplied material. Professional editing can improve order and clarity without increasing ownership, scope or certainty.
9
+ 3. Before saving the profile, compare the claims with the original source. Remove unsupported additions; ask only when a consequential ambiguity prevents a useful result. Keep this comparison internal, without a separate report or approval round. If helpful for a nontrivial rewrite, the existing bullet `evidenceSource` string can record a short source quotation; it is not printed and is not an independent verification claim.
10
+
11
+ Check each changed dimension: **technology · ownership · scope · mechanism · result · certainty**. A target title can go in the job objective; it cannot change an actual employment title, create years of experience in another stack, or become an item in skills.
12
+
13
+ ## Concrete rewrite boundaries
14
+
15
+ These are isolated editing examples, not candidate material or a profile to execute.
16
+
17
+ | Supplied statement | Faithful treatment | Unsupported addition |
18
+ | --- | --- | --- |
19
+ | Worked with Node.js and NestJS; wants a Java role | Keep the actual stack; use Java only in the target title until the user supplies Java skills | Add Java/Git to skills, or describe the period as Java experience |
20
+ | Participated in Redis and message-queue work | Keep “participated” and the unnamed message queue | Led architecture; Kafka/RocketMQ; cache prewarming; payment/event pipelines |
21
+ | Optimized queries; response time decreased about 40% under high concurrency | Retain that result and its qualification in the strongest relevant work bullet | Average/P99, 20ms, QPS, indexing or SQL execution-plan changes not supplied |
22
+ | Developed order, user and payment modules | Describe the modules in the work entry | Invent a separately named high-concurrency project, new project dates or a “core owner” role |
23
+ | Used Spring Boot and MySQL | List those technologies or the supplied use case | Expert JVM/JUC knowledge, deep index internals, distributed transactions |
24
+ | Bachelor degree and a major, without school/dates | Include the two known education fields; omit unknown fields | Guess a university, dates, GPA or claim that all education data is complete |
25
+
26
+ Do not turn a suggested outcome into a required ingredient of every bullet. A duty without a metric remains valid. One supplied project can be developed into a project entry when actual context and contributions are available; do not duplicate the same work as a second achievement just to fill a section. Keep a brief summary distinct from detailed work bullets.
27
+
28
+ ## Continue safely across turns
29
+
30
+ - User acceptance such as “use this version” authorizes progressing with known facts. It does not retroactively support a skill or achievement introduced by the Agent. Correct your unsupported additions before export; explain a material correction briefly instead of silently preserving it.
31
+ - When real candidate material arrives after an explicitly requested fictional example, build the candidate profile from that material. Reusing the layout is fine; filling over a fictional profile risks leaving invented skills and achievements behind.
32
+ - On a contact-only update, change only those fields and necessary resulting layout. Do not rewrite summary/skills/projects, change template, add qualifications or re-ask the whole questionnaire. If continuing in a new session, use the prior current profile/canvas and ask only if the current revision is genuinely ambiguous.
33
+ - Supplied wording may be strengthened only by stronger supplied facts; do not weaken explicit ownership merely because the source is chat. Conflicting dates or roles require a focused clarification or omission of the disputed claim, not guessing.
34
+
35
+ Use Draft for a requested partial canvas, not simply because optional fields are missing. Master preserves this run's known facts and does not certify their external truth. Missing values remain omitted/null. See 07-artifact-contract.md for data shapes and tool states.
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 1. Professional Seniority Signals
8
8
 
9
- Identify candidate level and calibrate narrative depth accordingly:
9
+ Use these archetypes to guide questions, not to infer facts. Years alone do not establish seniority, ownership or proficiency. Preserve the user’s stated role and responsibility; omit unsupported claims from the following illustrative patterns.
10
10
 
11
11
  | Seniority Tier | Core Value Proposition | Key Narrative Signals | Section Priority |
12
12
  |:---|:---|:---|:---|
@@ -19,6 +19,8 @@ Identify candidate level and calibrate narrative depth accordingly:
19
19
 
20
20
  ## 2. Role Archetypes Knowledge Base (`src/knowledge/roles/*.json`)
21
21
 
22
+ Read a role profile only for a specific positioning question after candidate facts are available. `mustHaveSkills`, `niceToHaveSkills` and `evidenceSignals` describe hiring expectations and question topics; they are never defaults for personal skills, mechanisms or accomplishments. A generic role name may cover several seniority levels.
23
+
22
24
  The skill ships with 9+ structured role profiles:
23
25
  - `ai-agent-engineer.json`: LLM Orchestration, RAG, Tool Calling, VectorDB, Prompt Engineering
24
26
  - `frontend.json`: React/Vue/Next.js, Web Vitals, Design Systems, State Management
@@ -31,7 +33,7 @@ The skill ships with 9+ structured role profiles:
31
33
 
32
34
  ## 3. Core Value Proposition Formulation
33
35
 
34
- Synthesize the 15~25 word Value Proposition headline following this formula:
36
+ If useful, write a short headline from supplied facts. The following formula is optional: omit years, strengths or impact when unknown. The example is fictional and must never fill a candidate record.
35
37
  $$\text{Value Proposition} = [\text{Target Role}] + [\text{Years/Domain Focus}] + [\text{Top 2 Signature Strengths}] + [\text{Concrete Impact Deliverable}]$$
36
38
 
37
39
  *Example*:
@@ -21,24 +21,12 @@ python3 scripts/evidence/analyze-jd.py --jd "path/to/jd.md" --json
21
21
 
22
22
  ## 2. Keyword Density & Highlighting Rules
23
23
 
24
- In `workspace/resume.html`, inject JD keywords to pass ATS automated screening while remaining natural for human reviewers:
24
+ Use JD terms only where the candidate has supplied matching experience. Keywords select or emphasize existing facts; they do not add skills to a Master or Variant. A technology named only by the vacancy remains a gap to discuss.
25
25
 
26
- - **Primary Stack (Top 3~5 Keywords)**: Wrap with `<strong>` tags inside bullet points where evidence exists;
27
- - **Technology Badges**: Place in `.tech-tags` or `.tech-badge` spans;
28
- - **Density Control**: Maintain keyword density around 2.5%~4.0% of total words to prevent ATS keyword stuffing penalties.
26
+ Prefer a few relevant, readable terms over repetition. There is no project-validated universal ATS keyword-density threshold. Do not claim automated screening success from keyword counts.
29
27
 
30
- ---
31
-
32
- ## 3. FAB (Feature-Advantage-Benefit) Bullet Engineering
33
-
34
- Structure every project bullet point using the FAB formula:
28
+ ## 3. Writing useful bullets
35
29
 
36
- ```
37
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
38
- │ Feature (技术动作)│ ────> │ Advantage (技术优势)│ ────> │ Benefit (业务价值) │
39
- │ Exact tech & tool │ │ Architectural gain│ │ Quantified impact│
40
- └─────────────────┘ └─────────────────┘ └─────────────────┘
41
- ```
30
+ Describe the supplied action and its context. Add the method and outcome only when the user provided them. FAB is an optional editing aid, not a requirement that every duty acquire an invented business impact.
42
31
 
43
- *Before (Weak)*: Worked on database and improved query performance.
44
- *After (FAB Standard)*: Refactored PostgreSQL indexing and introduced Redis multi-tier caching (**Feature**), cutting P99 query latency from 850ms to 45ms (**Advantage**), supporting 10x traffic spike during peak sales (**Benefit**).
32
+ For example, if the only fact is “optimized order queries”, a faithful rewrite is “Optimized order queries for the ecommerce service” only if that service context was supplied. Do not infer indexing, Redis caching, P99 latency or traffic multiples. Preserve “participated” versus “led”, and ask for consequential missing mechanisms instead of writing them as facts.
@@ -1,43 +1,30 @@
1
- # Reference Manual 04: Template Selection & Layout Geometries
1
+ # Template selection and readable composition
2
2
 
3
- > **"Layout geometry determines information hierarchy. Select the composition that earns the candidate's strongest evidence."**
3
+ Select for the candidate's actual amount of content, strongest evidence and explicit preference. A backend title alone does not determine the layout. The ten current IDs below are directory IDs accepted by the pipeline; metadata describes design intent, not visual or ATS certification.
4
4
 
5
- ---
5
+ | ID | Structure | Review before choosing |
6
+ | --- | --- | --- |
7
+ | minimal | Single column | Straight reading order; sparse content needs breathing room rather than compression |
8
+ | international-flow | Single column | Consider for linear prose; inspect language and line lengths |
9
+ | modern | Sidebar, 32:68 | Keep side content short; check narrow-column wrapping |
10
+ | creative-tech | Sidebar, 28:72 | Use only when the visual emphasis suits the user |
11
+ | data-analyst | Sidebar, 30:70 | Do not invent metrics to match the template name |
12
+ | executive | Banner and split columns | Needs suitable supplied leadership evidence; a title does not confer it |
13
+ | classic | Structured table | Check sparse fields and reading order |
14
+ | compact-dense | Dense two columns | For substantial supplied content; avoid for a short career description |
15
+ | academic-research | Dense single column | Research content must actually be supplied |
16
+ | startup-generalist | Modular cards | Check block balance with the actual sections |
6
17
 
7
- ## 1. Core Template Matrix (Baseline 4)
18
+ Use the existing search when no template was selected:
8
19
 
9
- | Template ID | Layout Geometry | Tone & Accent | Target Roles | Density | ATS Tier |
10
- |:---|:---|:---|:---|:---|:---|
11
- | `minimal` (`minimal-tech`) | Single-Column Linear Flow | Geek Minimal (Tech Blue `#2563eb`) | Backend, AI/LLM, Systems, DevOps, Fullstack | High | Tier 1 (Optimal) |
12
- | `modern` (`modern-split-sidebar`) | Two-Column Split (32:68 Dark Sidebar) | Deep Navy (`#254665`) + Sky Blue (`#38bdf8`) | AI Agent, Frontend, Fullstack, Mobile | Balanced | Tier 1 (Optimal) |
13
- | `executive` (`executive-split`) | Hero Banner + Two-Column (33:67 Split) | Executive Slate (`#1e293b`) + Teal (`#0f766e`) | Tech Director, Architect, PM, CTO | Balanced | Tier 1 (Optimal) |
14
- | `classic` (`table-structured`) | 6-Column Structured Grid Table | Corporate Blue (`#1d4ed8`) + Slate | Enterprise, Fintech, Hardware, State-Owned | High | Tier 1 (Optimal) |
15
-
16
- ---
17
-
18
- ## 2. Template Search Engine (`scripts/template/search-template.py`)
19
-
20
- Search for the optimal template via CLI:
21
20
  ```bash
22
- # Hybrid Search (Default Recommended)
23
- python3 scripts/template/search-template.py "AI Agent Engineer" --style "two-column-split" --target-pages 1
24
-
25
- # BM25 Keyword Search
26
- python3 scripts/template/search-template.py "Distributed Architect" --engine bm25 --json
27
-
28
- # Weighted Multi-Criteria Rule Search
29
- python3 scripts/template/search-template.py "Frontend Engineer" --engine weighted
21
+ python3 <skill-root>/scripts/template/search-template.py "<target role>" --target-pages 1 --summary
30
22
  ```
31
23
 
32
- ### Search Scoring Formulation (Weighted Scorer):
33
- $$\text{Score} = (\text{RoleMatch} \times 0.35) + (\text{StyleMatch} \times 0.25) + (\text{ATSTier} \times 0.20) + (\text{PageFit} \times 0.10) + (\text{Density} \times 0.10)$$
34
-
35
- ---
24
+ The summary returns the top three candidates with IDs and layout metadata; the existing `--json` option returns all metadata only when needed. For a simple, sparse resume, prefer a readable single-column structure from the table over a dense sidebar just because it has a higher role score. Do not load every template source or build a gallery for a single resume.
36
25
 
37
- ## 3. Instantiating the Intermediate HTML Canvas
26
+ The pipeline also ranks automatically if `--template` is omitted. Ranking does not inspect the final PDF's aesthetics. Inspect the selected output and report `templateUsed`; do not claim that all ten designs were visually compared if only one was rendered.
38
27
 
39
- ```bash
40
- python3 scripts/template/instantiate-resume.py --template modern --profile workspace/evidence-master.json --keywords "Python,LLM,RAG,FastAPI" --output workspace/resume.html
41
- ```
28
+ For experienced candidates, work evidence should be easy to find. Keep skill lists compact; avoid paragraphs claiming proficiency in every role keyword. A summary and a project section are optional, and should not repeat the same achievement. For sparse profiles, preserve honest whitespace, use a simple layout and ask for useful details only when needed. Do not fill a page with generic qualities or fabricated projects. For dense profiles, edit repetition before reducing type size or spacing.
42
29
 
43
- *The instantiator automatically inlines `src/templates/common/base.css` + `src/templates/{template}/style.css` into a single self-contained HTML file.*
30
+ Each template maintains `canvas.html`, `style.css`, `metadata.json`, `README.md` and a fictional `sample-profile.json`. Gallery previews use the same instantiator, combining common/base.css, template style.css and common/canvas-bindings.css. Read source only for a needed layout edit; never load gallery sample content to assemble candidate facts. Token tuning is described in 05-html-canvas-tokens.md. Multiple PDF pages require explicit page containers, regardless of metadata's maximum page count.
@@ -12,3 +12,16 @@ The pipeline isolates each run and records artifact hashes in manifest.json. Use
12
12
  `forge.py` 和 `instantiate-resume.py` 支持 `--font-preset system|arial-unicode`,默认保留系统字体。`arial-unicode` 显式使用本机 Arial Unicode MS;没有该字体时字体验收失败并返回 UNVERIFIED,不保证跨机器可用,也不自动下载字体。字体选择只改变画布样式,不改变 Master 事实,并记录在 Variant 的 source.fontPreset 和运行清单中。
13
13
 
14
14
  中文 PDF 若文本验收失败,检查 QA 每页的 missingCodepoints、missingFragments 与 extractedRadicals。部首字符可能来自字体字码映射差异,也可能存在真实缺字;不能仅凭这种提示放行。可选用本机可用字体、创建新运行并重新检查,不改写姓名/经历来绕过问题,也不把部首字符全部忽略。
15
+
16
+ ## What each check can actually establish
17
+
18
+ | Evidence | What it supports | What it cannot establish |
19
+ | --- | --- | --- |
20
+ | Original user material compared with rewritten claims | Fidelity to supplied facts | Independent verification of the user's history |
21
+ | Master/Variant hashes and bound text | Run provenance and rendering consistency | That Agent-written profile claims came from the user |
22
+ | Current PDF page/text/layout checks | Technical PDF acceptance | Complete optional information, ideal design or universal ATS support |
23
+ | Every page of the final PDF viewed | Actual visual appearance of those pages | Authenticity of the candidate's achievements |
24
+
25
+ Inspect the PDF itself using the host's PDF viewer or an available PDF-to-image tool, not a screen-media HTML preview. If no such tool is available, say the PDF's visual review is incomplete; keep the technical PASS distinction. Do not install a second rendering system just to repeat checks the pipeline already performed.
26
+
27
+ When a font mapping warning occurs, read the reported missing fragments/codepoints and compare with the source text and page appearance. A warning is a diagnostic clue, not a diagnosis or an automatic reason to force a specific font. Use an available explicit font only as a justified retry; preserve facts and recheck the new PDF. After the current export and review pass, deliver rather than creating more copies or rerunning unchanged checks.
@@ -62,3 +62,22 @@
62
62
  当前分页契约要求每个 `.resume-page` 对应一个 A4 页面,`--expected-pages` 为 1 或 2 的上限。一页文档可用上限 2;两页文档需由 Agent 显式建立两个页面容器。单个超高容器自然流入多页会被拒绝,不猜测浏览器分页后每页应有的内容。
63
63
 
64
64
  输入文档的来源说明保存在 Master 的 source.suppliedSource 中,包括 synthetic-simulation 等原始标签。它是来源元数据,不是新增候选人事实。字体预设单独记录为 Variant.source.fontPreset;不得把字体修订误记为事实变更。
65
+
66
+ ## 简短输入与交付入口
67
+
68
+ Agent 可直接整理裸 profile;只填写用户提供的值,删除未知字段及不需要的章节。以下尖括号仅说明字段含义,不能作为候选人数据执行:
69
+
70
+ ```json
71
+ {
72
+ "basics": {"name": "<用户姓名>", "title": "<目标岗位>"},
73
+ "skills": [{"category": "<分组>", "items": ["<用户提供的技能>"]}],
74
+ "experience": [{"company": "<公司>", "role": "<实际职务>",
75
+ "startDate": "<开始时间>", "endDate": "<结束时间>",
76
+ "bullets": [{"text": "<用户提供的职责或成果>"}]}],
77
+ "education": [{"degree": "<学历>", "field": "<专业>"}]
78
+ }
79
+ ```
80
+
81
+ 姓名和至少一个实质章节是当前 PDF 输入门槛;联系方式、学校、专业和日期允许未知。`missingFields` 仅列出 basics.name/title/email/phone 的缺失,空列表不表示所有字段完整,更不证明事实真实。
82
+
83
+ `forge.py --summary` 仅精简终端报告,包含当前状态、模板、错误、仅 html/pdf 的 outputs 和 manifest 路径;默认及 `--quiet` 仍保留完整 JSON。完整 manifest 与 QA 始终落盘。正常交付用 `--output resume/resume.pdf --html-output resume/resume.html` 创建验收副本;内部运行历史不作为用户默认交付清单。失败时副本可能仍为旧版本,不能据此报告本次成功。Draft 不使用这些验收副本选项。
@@ -111,6 +111,7 @@ def main():
111
111
  parser.add_argument('--expected-pages', type=int, choices=(1, 2), default=1)
112
112
  parser.add_argument('--auto-heal', action='store_true')
113
113
  parser.add_argument('--quiet', '-q', action='store_true')
114
+ parser.add_argument('--summary', action='store_true', help='Compact report with manifest path; full diagnostics stay on disk')
114
115
  args = parser.parse_args()
115
116
  report = {'schemaVersion': '1.0', 'runId': uuid.uuid4().hex, 'status': 'RUNNING',
116
117
  'stage': 'input', 'errors': [], 'warnings': [], 'checks': {}, 'outputs': {}}
@@ -264,7 +265,16 @@ def main():
264
265
  report.update(status='FAIL', outputs={})
265
266
  report['errors'].append('Could not persist manifest: ' + str(error))
266
267
  exit_code = 1
267
- print(json.dumps(report, ensure_ascii=False, indent=None if args.quiet else 2))
268
+ emitted = report
269
+ if args.summary:
270
+ emitted = {key: report[key] for key in ('runId', 'status', 'stage', 'templateUsed', 'fontPreset', 'errors', 'warnings', 'outputs') if key in report}
271
+ emitted['outputs'] = {}
272
+ if report['status'] in ('PASS', 'DRAFT'):
273
+ emitted['outputs']['html'] = str(Path(args.html_output).resolve()) if report['status'] == 'PASS' and args.html_output else report['outputs']['htmlCanvas']
274
+ if report['status'] == 'PASS':
275
+ emitted['outputs']['pdf'] = str(Path(args.output).resolve()) if args.output else report['outputs']['pdfDelivery']
276
+ emitted['manifest'] = str(run / 'manifest.json') if run else None
277
+ print(json.dumps(emitted, ensure_ascii=False, indent=None if args.quiet else 2))
268
278
  return exit_code
269
279
 
270
280
 
@@ -148,6 +148,37 @@ async function dependencies() {
148
148
  return { pw, PDFDocument, pdfjs };
149
149
  }
150
150
 
151
+ // Readiness does not generate candidate artifacts or certify a resume.
152
+ async function checkRuntime() {
153
+ const result = { status: 'UNVERIFIED', stage: 'runtime', errors: [], checks: {} };
154
+ const version = process.versions.node.split('.').map(Number);
155
+ if (version[0] < 22 || (version[0] === 22 && version[1] < 13)) {
156
+ result.errors.push('Node.js 22.13+ is required');
157
+ }
158
+ for (const [name, candidates] of [
159
+ ['playwright', ['playwright', 'playwright-core']],
160
+ ['pdf-lib', ['pdf-lib']],
161
+ ['pdfjs-dist', ['pdfjs-dist/legacy/build/pdf.mjs']]
162
+ ]) {
163
+ const available = candidates.some(candidate => {
164
+ try { require.resolve(candidate); return true; } catch { return false; }
165
+ });
166
+ result.checks[name] = available ? 'AVAILABLE' : 'MISSING';
167
+ if (!available) result.errors.push(`Missing dependency: ${name}`);
168
+ }
169
+ if (!result.errors.length) {
170
+ let browser;
171
+ try {
172
+ const deps = await dependencies();
173
+ browser = await launchBrowser(deps.pw);
174
+ result.checks.browser = browser.version();
175
+ result.status = 'READY';
176
+ } catch (error) { result.errors.push(error.message); }
177
+ finally { if (browser) await browser.close(); }
178
+ }
179
+ return result;
180
+ }
181
+
151
182
  async function systemBrowsers() {
152
183
  const home = require('node:os').homedir();
153
184
  const candidates = [
@@ -335,6 +366,17 @@ async function run(html, { expectedPages = 1, autoHeal = false, outputPdf } = {}
335
366
  }
336
367
 
337
368
  async function cli(args = process.argv.slice(2), defaults = {}) {
369
+ if (args.length === 1 && ['--help', '-h'].includes(args[0])) {
370
+ process.stdout.write('Usage: browser-engine.js <resume.html> [--output <resume.pdf>] [--expected-pages 1|2] [--auto-heal]\n browser-engine.js --check-runtime\n');
371
+ process.exitCode = 0;
372
+ return;
373
+ }
374
+ if (args.length === 1 && args[0] === '--check-runtime') {
375
+ const result = await checkRuntime();
376
+ process.stdout.write(JSON.stringify(result) + '\n');
377
+ process.exitCode = result.status === 'READY' ? 0 : 2;
378
+ return result;
379
+ }
338
380
  let html = 'workspace/resume.html';
339
381
  const options = { ...defaults };
340
382
  const positional = [];
@@ -382,6 +382,7 @@ def main():
382
382
  parser.add_argument("--engine", "-e", default="hybrid", choices=["hybrid", "weighted", "bm25"], help="Scoring engine")
383
383
  parser.add_argument("--json", action="store_true", help="Output raw JSON array")
384
384
 
385
+ parser.add_argument("--summary", action="store_true", help="Compact JSON with the top three ranked layouts; no full metadata")
385
386
  args = parser.parse_args()
386
387
  target_role = args.named_role or args.role
387
388
  if not target_role:
@@ -396,6 +397,14 @@ def main():
396
397
  engine=args.engine
397
398
  )
398
399
 
400
+ if args.summary:
401
+ print(json.dumps({"totalMatches": len(results), "candidates": [
402
+ {"id": item["id"], "name": item.get("name"), "score": item["matchScore"],
403
+ "layout": item.get("layout", {})}
404
+ for item in results[:3]
405
+ ]}, ensure_ascii=False, indent=2))
406
+ return
407
+
399
408
  if args.json:
400
409
  print(json.dumps(results, ensure_ascii=False, indent=2))
401
410
  return
package/skill.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/skill.json",
3
3
  "name": "knowme-careerforge",
4
4
  "displayName": "KnowMe CareerForge",
5
- "version": "0.0.6",
5
+ "version": "0.0.7",
6
6
  "description": "An agent-native skill for self-discovery, career positioning, and tailored resume engineering. Know yourself. Define your direction. Forge your opportunity.",
7
7
  "author": "Miles <https://github.com/Max-Samson>",
8
8
  "license": "MIT",
@@ -38,10 +38,11 @@
38
38
  "writing-assistant"
39
39
  ],
40
40
  "installation": {
41
- "claude": "cp -r knowme-careerforge-skill ~/.claude/skills/knowme-careerforge",
42
- "codex": "cp -r knowme-careerforge-skill ~/.codex/skills/knowme-careerforge",
43
- "cursor": "cp SKILL.md .cursor/rules/knowme-careerforge.mdc",
44
- "windsurf": "cat SKILL.md >> .windsurfrules",
45
- "opencode": "cp -r knowme-careerforge-skill ~/.opencode/skills/knowme-careerforge"
41
+ "claude": "knowme init --ai claude",
42
+ "codex": "knowme init --ai codex",
43
+ "cursor": "knowme init --ai cursor",
44
+ "windsurf": "knowme init --ai windsurf",
45
+ "gemini": "knowme init --ai gemini",
46
+ "opencode": "knowme init --ai opencode"
46
47
  }
47
48
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.6",
2
+ "version": "0.0.7",
3
3
  "totalRoles": 9,
4
4
  "totalTemplates": 10,
5
5
  "roles": [
@@ -1,5 +1,35 @@
1
- # Organize user-supplied facts
1
+ # Turn supplied facts into resume claims
2
2
 
3
- Use the user's descriptions, prior resume and explicitly supplied supporting material. Repository scanning is not a supported candidate input mode. Reuse known information; ask progressive follow-up questions only for consequential gaps. Do not invent dates, employers, degrees or metrics, or weaken stated ownership solely because it came from chat.
3
+ Read this when composing or materially rewriting candidate content. Compare with the user's original messages or supplied resume, not just an Agent-generated profile. Tools verify that profile text survives rendering; they cannot establish that the profile was faithful in the first place.
4
4
 
5
- Store incomplete information as Draft and reviewed supplied facts as Master. Derive role-specific Variant content without changing the Master. Unknown values remain omitted/null. Follow the shared lifecycle and error rules in 07-artifact-contract.md.
5
+ ## Compose, then check against the source
6
+
7
+ 1. Identify supplied facts and the target role separately. Treat role/JD knowledge as requirements to compare, not personal qualifications. Do not read role profiles for a straightforward rewrite; consult them only for a specific positioning question.
8
+ 2. Write a concise draft of the content. Every skill, responsibility, mechanism, result and level of proficiency must be supported by supplied material. Professional editing can improve order and clarity without increasing ownership, scope or certainty.
9
+ 3. Before saving the profile, compare the claims with the original source. Remove unsupported additions; ask only when a consequential ambiguity prevents a useful result. Keep this comparison internal, without a separate report or approval round. If helpful for a nontrivial rewrite, the existing bullet `evidenceSource` string can record a short source quotation; it is not printed and is not an independent verification claim.
10
+
11
+ Check each changed dimension: **technology · ownership · scope · mechanism · result · certainty**. A target title can go in the job objective; it cannot change an actual employment title, create years of experience in another stack, or become an item in skills.
12
+
13
+ ## Concrete rewrite boundaries
14
+
15
+ These are isolated editing examples, not candidate material or a profile to execute.
16
+
17
+ | Supplied statement | Faithful treatment | Unsupported addition |
18
+ | --- | --- | --- |
19
+ | Worked with Node.js and NestJS; wants a Java role | Keep the actual stack; use Java only in the target title until the user supplies Java skills | Add Java/Git to skills, or describe the period as Java experience |
20
+ | Participated in Redis and message-queue work | Keep “participated” and the unnamed message queue | Led architecture; Kafka/RocketMQ; cache prewarming; payment/event pipelines |
21
+ | Optimized queries; response time decreased about 40% under high concurrency | Retain that result and its qualification in the strongest relevant work bullet | Average/P99, 20ms, QPS, indexing or SQL execution-plan changes not supplied |
22
+ | Developed order, user and payment modules | Describe the modules in the work entry | Invent a separately named high-concurrency project, new project dates or a “core owner” role |
23
+ | Used Spring Boot and MySQL | List those technologies or the supplied use case | Expert JVM/JUC knowledge, deep index internals, distributed transactions |
24
+ | Bachelor degree and a major, without school/dates | Include the two known education fields; omit unknown fields | Guess a university, dates, GPA or claim that all education data is complete |
25
+
26
+ Do not turn a suggested outcome into a required ingredient of every bullet. A duty without a metric remains valid. One supplied project can be developed into a project entry when actual context and contributions are available; do not duplicate the same work as a second achievement just to fill a section. Keep a brief summary distinct from detailed work bullets.
27
+
28
+ ## Continue safely across turns
29
+
30
+ - User acceptance such as “use this version” authorizes progressing with known facts. It does not retroactively support a skill or achievement introduced by the Agent. Correct your unsupported additions before export; explain a material correction briefly instead of silently preserving it.
31
+ - When real candidate material arrives after an explicitly requested fictional example, build the candidate profile from that material. Reusing the layout is fine; filling over a fictional profile risks leaving invented skills and achievements behind.
32
+ - On a contact-only update, change only those fields and necessary resulting layout. Do not rewrite summary/skills/projects, change template, add qualifications or re-ask the whole questionnaire. If continuing in a new session, use the prior current profile/canvas and ask only if the current revision is genuinely ambiguous.
33
+ - Supplied wording may be strengthened only by stronger supplied facts; do not weaken explicit ownership merely because the source is chat. Conflicting dates or roles require a focused clarification or omission of the disputed claim, not guessing.
34
+
35
+ Use Draft for a requested partial canvas, not simply because optional fields are missing. Master preserves this run's known facts and does not certify their external truth. Missing values remain omitted/null. See 07-artifact-contract.md for data shapes and tool states.
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 1. Professional Seniority Signals
8
8
 
9
- Identify candidate level and calibrate narrative depth accordingly:
9
+ Use these archetypes to guide questions, not to infer facts. Years alone do not establish seniority, ownership or proficiency. Preserve the user’s stated role and responsibility; omit unsupported claims from the following illustrative patterns.
10
10
 
11
11
  | Seniority Tier | Core Value Proposition | Key Narrative Signals | Section Priority |
12
12
  |:---|:---|:---|:---|
@@ -19,6 +19,8 @@ Identify candidate level and calibrate narrative depth accordingly:
19
19
 
20
20
  ## 2. Role Archetypes Knowledge Base (`src/knowledge/roles/*.json`)
21
21
 
22
+ Read a role profile only for a specific positioning question after candidate facts are available. `mustHaveSkills`, `niceToHaveSkills` and `evidenceSignals` describe hiring expectations and question topics; they are never defaults for personal skills, mechanisms or accomplishments. A generic role name may cover several seniority levels.
23
+
22
24
  The skill ships with 9+ structured role profiles:
23
25
  - `ai-agent-engineer.json`: LLM Orchestration, RAG, Tool Calling, VectorDB, Prompt Engineering
24
26
  - `frontend.json`: React/Vue/Next.js, Web Vitals, Design Systems, State Management
@@ -31,7 +33,7 @@ The skill ships with 9+ structured role profiles:
31
33
 
32
34
  ## 3. Core Value Proposition Formulation
33
35
 
34
- Synthesize the 15~25 word Value Proposition headline following this formula:
36
+ If useful, write a short headline from supplied facts. The following formula is optional: omit years, strengths or impact when unknown. The example is fictional and must never fill a candidate record.
35
37
  $$\text{Value Proposition} = [\text{Target Role}] + [\text{Years/Domain Focus}] + [\text{Top 2 Signature Strengths}] + [\text{Concrete Impact Deliverable}]$$
36
38
 
37
39
  *Example*:
@@ -21,24 +21,12 @@ python3 scripts/evidence/analyze-jd.py --jd "path/to/jd.md" --json
21
21
 
22
22
  ## 2. Keyword Density & Highlighting Rules
23
23
 
24
- In `workspace/resume.html`, inject JD keywords to pass ATS automated screening while remaining natural for human reviewers:
24
+ Use JD terms only where the candidate has supplied matching experience. Keywords select or emphasize existing facts; they do not add skills to a Master or Variant. A technology named only by the vacancy remains a gap to discuss.
25
25
 
26
- - **Primary Stack (Top 3~5 Keywords)**: Wrap with `<strong>` tags inside bullet points where evidence exists;
27
- - **Technology Badges**: Place in `.tech-tags` or `.tech-badge` spans;
28
- - **Density Control**: Maintain keyword density around 2.5%~4.0% of total words to prevent ATS keyword stuffing penalties.
26
+ Prefer a few relevant, readable terms over repetition. There is no project-validated universal ATS keyword-density threshold. Do not claim automated screening success from keyword counts.
29
27
 
30
- ---
31
-
32
- ## 3. FAB (Feature-Advantage-Benefit) Bullet Engineering
33
-
34
- Structure every project bullet point using the FAB formula:
28
+ ## 3. Writing useful bullets
35
29
 
36
- ```
37
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
38
- │ Feature (技术动作)│ ────> │ Advantage (技术优势)│ ────> │ Benefit (业务价值) │
39
- │ Exact tech & tool │ │ Architectural gain│ │ Quantified impact│
40
- └─────────────────┘ └─────────────────┘ └─────────────────┘
41
- ```
30
+ Describe the supplied action and its context. Add the method and outcome only when the user provided them. FAB is an optional editing aid, not a requirement that every duty acquire an invented business impact.
42
31
 
43
- *Before (Weak)*: Worked on database and improved query performance.
44
- *After (FAB Standard)*: Refactored PostgreSQL indexing and introduced Redis multi-tier caching (**Feature**), cutting P99 query latency from 850ms to 45ms (**Advantage**), supporting 10x traffic spike during peak sales (**Benefit**).
32
+ For example, if the only fact is “optimized order queries”, a faithful rewrite is “Optimized order queries for the ecommerce service” only if that service context was supplied. Do not infer indexing, Redis caching, P99 latency or traffic multiples. Preserve “participated” versus “led”, and ask for consequential missing mechanisms instead of writing them as facts.
@@ -1,43 +1,30 @@
1
- # Reference Manual 04: Template Selection & Layout Geometries
1
+ # Template selection and readable composition
2
2
 
3
- > **"Layout geometry determines information hierarchy. Select the composition that earns the candidate's strongest evidence."**
3
+ Select for the candidate's actual amount of content, strongest evidence and explicit preference. A backend title alone does not determine the layout. The ten current IDs below are directory IDs accepted by the pipeline; metadata describes design intent, not visual or ATS certification.
4
4
 
5
- ---
5
+ | ID | Structure | Review before choosing |
6
+ | --- | --- | --- |
7
+ | minimal | Single column | Straight reading order; sparse content needs breathing room rather than compression |
8
+ | international-flow | Single column | Consider for linear prose; inspect language and line lengths |
9
+ | modern | Sidebar, 32:68 | Keep side content short; check narrow-column wrapping |
10
+ | creative-tech | Sidebar, 28:72 | Use only when the visual emphasis suits the user |
11
+ | data-analyst | Sidebar, 30:70 | Do not invent metrics to match the template name |
12
+ | executive | Banner and split columns | Needs suitable supplied leadership evidence; a title does not confer it |
13
+ | classic | Structured table | Check sparse fields and reading order |
14
+ | compact-dense | Dense two columns | For substantial supplied content; avoid for a short career description |
15
+ | academic-research | Dense single column | Research content must actually be supplied |
16
+ | startup-generalist | Modular cards | Check block balance with the actual sections |
6
17
 
7
- ## 1. Core Template Matrix (Baseline 4)
18
+ Use the existing search when no template was selected:
8
19
 
9
- | Template ID | Layout Geometry | Tone & Accent | Target Roles | Density | ATS Tier |
10
- |:---|:---|:---|:---|:---|:---|
11
- | `minimal` (`minimal-tech`) | Single-Column Linear Flow | Geek Minimal (Tech Blue `#2563eb`) | Backend, AI/LLM, Systems, DevOps, Fullstack | High | Tier 1 (Optimal) |
12
- | `modern` (`modern-split-sidebar`) | Two-Column Split (32:68 Dark Sidebar) | Deep Navy (`#254665`) + Sky Blue (`#38bdf8`) | AI Agent, Frontend, Fullstack, Mobile | Balanced | Tier 1 (Optimal) |
13
- | `executive` (`executive-split`) | Hero Banner + Two-Column (33:67 Split) | Executive Slate (`#1e293b`) + Teal (`#0f766e`) | Tech Director, Architect, PM, CTO | Balanced | Tier 1 (Optimal) |
14
- | `classic` (`table-structured`) | 6-Column Structured Grid Table | Corporate Blue (`#1d4ed8`) + Slate | Enterprise, Fintech, Hardware, State-Owned | High | Tier 1 (Optimal) |
15
-
16
- ---
17
-
18
- ## 2. Template Search Engine (`scripts/template/search-template.py`)
19
-
20
- Search for the optimal template via CLI:
21
20
  ```bash
22
- # Hybrid Search (Default Recommended)
23
- python3 scripts/template/search-template.py "AI Agent Engineer" --style "two-column-split" --target-pages 1
24
-
25
- # BM25 Keyword Search
26
- python3 scripts/template/search-template.py "Distributed Architect" --engine bm25 --json
27
-
28
- # Weighted Multi-Criteria Rule Search
29
- python3 scripts/template/search-template.py "Frontend Engineer" --engine weighted
21
+ python3 <skill-root>/scripts/template/search-template.py "<target role>" --target-pages 1 --summary
30
22
  ```
31
23
 
32
- ### Search Scoring Formulation (Weighted Scorer):
33
- $$\text{Score} = (\text{RoleMatch} \times 0.35) + (\text{StyleMatch} \times 0.25) + (\text{ATSTier} \times 0.20) + (\text{PageFit} \times 0.10) + (\text{Density} \times 0.10)$$
34
-
35
- ---
24
+ The summary returns the top three candidates with IDs and layout metadata; the existing `--json` option returns all metadata only when needed. For a simple, sparse resume, prefer a readable single-column structure from the table over a dense sidebar just because it has a higher role score. Do not load every template source or build a gallery for a single resume.
36
25
 
37
- ## 3. Instantiating the Intermediate HTML Canvas
26
+ The pipeline also ranks automatically if `--template` is omitted. Ranking does not inspect the final PDF's aesthetics. Inspect the selected output and report `templateUsed`; do not claim that all ten designs were visually compared if only one was rendered.
38
27
 
39
- ```bash
40
- python3 scripts/template/instantiate-resume.py --template modern --profile workspace/evidence-master.json --keywords "Python,LLM,RAG,FastAPI" --output workspace/resume.html
41
- ```
28
+ For experienced candidates, work evidence should be easy to find. Keep skill lists compact; avoid paragraphs claiming proficiency in every role keyword. A summary and a project section are optional, and should not repeat the same achievement. For sparse profiles, preserve honest whitespace, use a simple layout and ask for useful details only when needed. Do not fill a page with generic qualities or fabricated projects. For dense profiles, edit repetition before reducing type size or spacing.
42
29
 
43
- *The instantiator automatically inlines `src/templates/common/base.css` + `src/templates/{template}/style.css` into a single self-contained HTML file.*
30
+ Each template maintains `canvas.html`, `style.css`, `metadata.json`, `README.md` and a fictional `sample-profile.json`. Gallery previews use the same instantiator, combining common/base.css, template style.css and common/canvas-bindings.css. Read source only for a needed layout edit; never load gallery sample content to assemble candidate facts. Token tuning is described in 05-html-canvas-tokens.md. Multiple PDF pages require explicit page containers, regardless of metadata's maximum page count.
@@ -12,3 +12,16 @@ The pipeline isolates each run and records artifact hashes in manifest.json. Use
12
12
  `forge.py` 和 `instantiate-resume.py` 支持 `--font-preset system|arial-unicode`,默认保留系统字体。`arial-unicode` 显式使用本机 Arial Unicode MS;没有该字体时字体验收失败并返回 UNVERIFIED,不保证跨机器可用,也不自动下载字体。字体选择只改变画布样式,不改变 Master 事实,并记录在 Variant 的 source.fontPreset 和运行清单中。
13
13
 
14
14
  中文 PDF 若文本验收失败,检查 QA 每页的 missingCodepoints、missingFragments 与 extractedRadicals。部首字符可能来自字体字码映射差异,也可能存在真实缺字;不能仅凭这种提示放行。可选用本机可用字体、创建新运行并重新检查,不改写姓名/经历来绕过问题,也不把部首字符全部忽略。
15
+
16
+ ## What each check can actually establish
17
+
18
+ | Evidence | What it supports | What it cannot establish |
19
+ | --- | --- | --- |
20
+ | Original user material compared with rewritten claims | Fidelity to supplied facts | Independent verification of the user's history |
21
+ | Master/Variant hashes and bound text | Run provenance and rendering consistency | That Agent-written profile claims came from the user |
22
+ | Current PDF page/text/layout checks | Technical PDF acceptance | Complete optional information, ideal design or universal ATS support |
23
+ | Every page of the final PDF viewed | Actual visual appearance of those pages | Authenticity of the candidate's achievements |
24
+
25
+ Inspect the PDF itself using the host's PDF viewer or an available PDF-to-image tool, not a screen-media HTML preview. If no such tool is available, say the PDF's visual review is incomplete; keep the technical PASS distinction. Do not install a second rendering system just to repeat checks the pipeline already performed.
26
+
27
+ When a font mapping warning occurs, read the reported missing fragments/codepoints and compare with the source text and page appearance. A warning is a diagnostic clue, not a diagnosis or an automatic reason to force a specific font. Use an available explicit font only as a justified retry; preserve facts and recheck the new PDF. After the current export and review pass, deliver rather than creating more copies or rerunning unchanged checks.
@@ -62,3 +62,22 @@
62
62
  当前分页契约要求每个 `.resume-page` 对应一个 A4 页面,`--expected-pages` 为 1 或 2 的上限。一页文档可用上限 2;两页文档需由 Agent 显式建立两个页面容器。单个超高容器自然流入多页会被拒绝,不猜测浏览器分页后每页应有的内容。
63
63
 
64
64
  输入文档的来源说明保存在 Master 的 source.suppliedSource 中,包括 synthetic-simulation 等原始标签。它是来源元数据,不是新增候选人事实。字体预设单独记录为 Variant.source.fontPreset;不得把字体修订误记为事实变更。
65
+
66
+ ## 简短输入与交付入口
67
+
68
+ Agent 可直接整理裸 profile;只填写用户提供的值,删除未知字段及不需要的章节。以下尖括号仅说明字段含义,不能作为候选人数据执行:
69
+
70
+ ```json
71
+ {
72
+ "basics": {"name": "<用户姓名>", "title": "<目标岗位>"},
73
+ "skills": [{"category": "<分组>", "items": ["<用户提供的技能>"]}],
74
+ "experience": [{"company": "<公司>", "role": "<实际职务>",
75
+ "startDate": "<开始时间>", "endDate": "<结束时间>",
76
+ "bullets": [{"text": "<用户提供的职责或成果>"}]}],
77
+ "education": [{"degree": "<学历>", "field": "<专业>"}]
78
+ }
79
+ ```
80
+
81
+ 姓名和至少一个实质章节是当前 PDF 输入门槛;联系方式、学校、专业和日期允许未知。`missingFields` 仅列出 basics.name/title/email/phone 的缺失,空列表不表示所有字段完整,更不证明事实真实。
82
+
83
+ `forge.py --summary` 仅精简终端报告,包含当前状态、模板、错误、仅 html/pdf 的 outputs 和 manifest 路径;默认及 `--quiet` 仍保留完整 JSON。完整 manifest 与 QA 始终落盘。正常交付用 `--output resume/resume.pdf --html-output resume/resume.html` 创建验收副本;内部运行历史不作为用户默认交付清单。失败时副本可能仍为旧版本,不能据此报告本次成功。Draft 不使用这些验收副本选项。
@@ -1,5 +1,5 @@
1
1
  /* Binding components shared by the ten fact-free canvas.html layouts.
2
- Loaded after the preview stylesheet; scoped so previews stay unchanged. */
2
+ Loaded after each template stylesheet for both gallery and candidate output. */
3
3
  .bound-canvas {
4
4
  font-family: var(--resume-font-body, var(--primitive-font-sans));
5
5
  font-size: var(--resume-font-size-body, 9.2pt);
@@ -15,7 +15,7 @@
15
15
  .bound-canvas .contact-item { white-space: pre-wrap; }
16
16
  .bound-canvas .resume-section { margin-bottom: var(--resume-space-section, 12pt); }
17
17
  .bound-canvas .section-title { font-size: var(--resume-font-size-h2, 12pt); margin-bottom: 6pt; }
18
- .bound-canvas .item-header { display: flex; flex-wrap: wrap; gap: 3pt 8pt; align-items: baseline; }
18
+ .bound-canvas .item-header { display: flex; flex-wrap: wrap; gap: 3pt 8pt; align-items: baseline; justify-content: flex-start; }
19
19
  .bound-canvas .date-range { white-space: normal; margin-left: auto; }
20
20
  .bound-canvas .role-badge, .bound-canvas .tech-tag { white-space: normal; }
21
21
  .bound-canvas .experience-item, .bound-canvas .project-item, .bound-canvas .education-item {
@@ -4,7 +4,7 @@
4
4
 
5
5
  - **版式风格**:单栏线性流 (Single-Column Linear Flow)
6
6
  - **视觉色系**:极客蓝 (`#2563eb`) + 板岩灰阶 (`#0f172a`, `#334155`)
7
- - **ATS 评级**:Tier 1 (Optimal - 100% 完美解析)
7
+ - **ATS 评级**:Tier 1(设计意图,不代表第三方 ATS 认证)
8
8
  - **目标页数**:严格 1 页 (支持微调扩展至 2 页)
9
9
  - **核心 Tokens**:
10
10
  - `--resume-space-section`: `11pt` (默认)
@@ -19,3 +19,5 @@
19
19
  - `metadata.json`:模板选择与布局元数据。
20
20
 
21
21
  在项目根目录运行 `python3 scripts/build/build-gallery.py` 生成画廊。预览与实际简历共用实例化器及完整 CSS 链;生成的 HTML 位于 `output/templates_gallery/`,不回写到模板源目录。
22
+
23
+ 学历、专业和机构由公共绑定样式相邻排列,只有实际日期向右对齐;学校或日期未知时不以占位文字补齐。资料较少时应保留合理留白,不为填满高密度版式添加经历。