knowme-careerforge-skill 0.0.6 → 0.0.8

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.
Files changed (75) hide show
  1. package/AGENT.md +7 -6
  2. package/ARCHITECTURE.md +21 -14
  3. package/README.md +36 -25
  4. package/README.zh-CN.md +36 -25
  5. package/SKILL.md +42 -27
  6. package/agents/claude/knowme-careerforge.md +1 -1
  7. package/agents/codex/knowme-careerforge.yaml +2 -18
  8. package/agents/cursor/knowme-careerforge.mdc +1 -1
  9. package/agents/gemini/knowme-careerforge.json +1 -1
  10. package/agents/opencode/skill.yaml +1 -1
  11. package/agents/windsurf/knowme-careerforge.rules +1 -1
  12. package/dist/cli/src/commands/init.js +51 -32
  13. package/dist/cli/src/index.js +22 -14
  14. package/package.json +1 -1
  15. package/references/01-evidence-mining.md +110 -3
  16. package/references/02-career-goal.md +36 -14
  17. package/references/03-jd-analysis.md +13 -15
  18. package/references/04-template-selection.md +27 -35
  19. package/references/05-html-canvas-tokens.md +4 -2
  20. package/references/06-qa-and-rendering.md +50 -3
  21. package/references/07-artifact-contract.md +39 -6
  22. package/scripts/Agent.md +3 -3
  23. package/scripts/build/build-gallery.py +2 -1
  24. package/scripts/build/release.py +3 -2
  25. package/scripts/evidence/analyze-jd.py +49 -8
  26. package/scripts/evidence/extract-evidence.py +17 -391
  27. package/scripts/pipeline/forge.py +165 -81
  28. package/scripts/rendering/browser-engine.js +47 -1
  29. package/scripts/template/instantiate-resume.py +5 -3
  30. package/scripts/template/search-template.py +9 -0
  31. package/skill.json +7 -6
  32. package/src/knowledge/career/seniority-signals.json +1 -0
  33. package/src/knowledge/index.json +176 -2
  34. package/src/knowledge/resume/action-verbs.json +3 -2
  35. package/src/knowledge/resume/fab-model.json +5 -4
  36. package/src/knowledge/resume-schema.json +1 -1
  37. package/src/knowledge/templates.json +174 -0
  38. package/src/references/01-evidence-mining.md +110 -3
  39. package/src/references/02-career-goal.md +36 -14
  40. package/src/references/03-jd-analysis.md +13 -15
  41. package/src/references/04-template-selection.md +27 -35
  42. package/src/references/05-html-canvas-tokens.md +4 -2
  43. package/src/references/06-qa-and-rendering.md +50 -3
  44. package/src/references/07-artifact-contract.md +39 -6
  45. package/src/templates/academic-research/canvas.html +2 -1
  46. package/src/templates/classic/canvas.html +2 -1
  47. package/src/templates/classic/style.css +90 -28
  48. package/src/templates/common/base.css +19 -3
  49. package/src/templates/common/canvas-bindings.css +248 -13
  50. package/src/templates/compact-dense/style.css +5 -1
  51. package/src/templates/creative-tech/style.css +30 -1
  52. package/src/templates/data-analyst/style.css +31 -1
  53. package/src/templates/editorial/README.md +7 -0
  54. package/src/templates/editorial/canvas.html +22 -0
  55. package/src/templates/editorial/metadata.json +36 -0
  56. package/src/templates/editorial/sample-profile.json +86 -0
  57. package/src/templates/editorial/style.css +24 -0
  58. package/src/templates/executive/style.css +52 -18
  59. package/src/templates/graduate/README.md +7 -0
  60. package/src/templates/graduate/canvas.html +22 -0
  61. package/src/templates/graduate/metadata.json +38 -0
  62. package/src/templates/graduate/sample-profile.json +60 -0
  63. package/src/templates/graduate/style.css +24 -0
  64. package/src/templates/international-flow/canvas.html +2 -1
  65. package/src/templates/minimal/README.md +3 -1
  66. package/src/templates/minimal/canvas.html +3 -2
  67. package/src/templates/minimal/style.css +6 -0
  68. package/src/templates/modern/style.css +43 -55
  69. package/src/templates/project-focus/README.md +7 -0
  70. package/src/templates/project-focus/canvas.html +22 -0
  71. package/src/templates/project-focus/metadata.json +36 -0
  72. package/src/templates/project-focus/sample-profile.json +93 -0
  73. package/src/templates/project-focus/style.css +24 -0
  74. package/src/templates/startup-generalist/canvas.html +2 -1
  75. package/src/templates/startup-generalist/style.css +15 -8
@@ -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.8
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.8';
62
62
  }
63
63
  }
64
64
  catch { }
65
- return '0.0.6';
65
+ return '0.0.8';
66
66
  }
67
67
  function showHelp() {
68
68
  console.log(`
@@ -75,30 +75,34 @@ Usage:
75
75
 
76
76
  Commands:
77
77
  forge Isolated user facts -> variant -> canvas -> verified PDF
78
- render Multi-strategy deterministic A4 PDF export
78
+ render Diagnostic PDF export; use forge for paired delivery
79
79
  init Install and configure Skill for AI Agent platforms (cursor, claude, codex, windsurf, gemini, opencode)
80
80
  list Display all available role profiles and HTML templates
81
81
  search <role> Search and rank templates for a specific role (e.g. knowme search "AI Agent Engineer")
82
- validate Validate working canvas HTML layout & ATS compliance
82
+ validate Diagnostic print/PDF checks; does not publish a delivery pair
83
83
  gallery Build & refresh static HTML template gallery
84
84
  test Run full automated test suite
85
85
  help Show this help message
86
86
 
87
87
  Options (for forge):
88
- --profile-json <file> User/Agent prepared facts or Master document
89
- --workspace <dir> Parent for isolated run directories (default: workspace/runs)
88
+ --profile-json <file> Facts file, or - for JSON on stdin
89
+ --html-input <file> Existing edited HTML, or - for HTML on stdin
90
+ --keep-workspace Retain diagnostic archive (default: temporary staging)
91
+ --workspace <dir> Explicit archive parent; enables retention
90
92
  --draft Create a draft canvas without PDF delivery
91
93
  --role <title> Target role title
92
94
  --jd <file|text> Target job description
93
- --template, -t <id> Template ID (minimal, modern, executive, classic, academic-research, international-flow, creative-tech, compact-dense, startup-generalist, data-analyst)
95
+ --template, -t <id> Template ID (minimal, modern, executive, classic, academic-research, international-flow, creative-tech, compact-dense, startup-generalist, data-analyst, editorial, graduate, project-focus)
94
96
  --name <name> Candidate name override
95
- --output, -o <path> Optional verified PDF copy (default: isolated run)
97
+ --output, -o <path> Verified PDF destination (default: resume/resume.pdf)
96
98
  --font-preset <name> system or arial-unicode (requires local Arial Unicode MS)
97
- --auto-heal Enable heuristic token auto-healing to eliminate A4 height overflow
98
- --quiet, -q Quiet execution (compact JSON output)
99
+ --auto-heal Attempt bounded spacing/type tuning; unresolved overflow fails
100
+ --html-output <path> HTML destination (default: beside the PDF)
101
+ --summary Compact report; default in clean mode
102
+ --quiet, -q Single-line JSON; does not change file retention
99
103
  Examples:
100
104
  knowme forge --profile-json candidate.json --role "AI Agent Engineer" --template modern
101
- knowme render workspace/resume.html workspace/resume.pdf
105
+ knowme forge --html-input - # Supply complete edited HTML on stdin
102
106
  knowme init --ai codex
103
107
  knowme init --all
104
108
  `);
@@ -119,8 +123,9 @@ function main() {
119
123
  break;
120
124
  }
121
125
  case 'extract': {
122
- console.error('Repository-to-resume extraction is not supported. Use user-provided facts with forge --profile-json.');
123
- process.exitCode = 1;
126
+ const scriptPath = path.join(rootDir, 'scripts', 'evidence', 'extract-evidence.py');
127
+ const proc = child_process.spawnSync('python3', [scriptPath, ...args.slice(1)], { stdio: 'inherit' });
128
+ process.exitCode = proc.status || 1;
124
129
  break;
125
130
  }
126
131
  case 'render': {
@@ -203,9 +208,12 @@ function main() {
203
208
  case 'help':
204
209
  case '--help':
205
210
  case '-h':
206
- default:
207
211
  showHelp();
208
212
  break;
213
+ default:
214
+ console.error(`Unknown command: ${command}. Run knowme help for supported commands.`);
215
+ process.exitCode = 1;
216
+ break;
209
217
  }
210
218
  }
211
219
  if (require.main === module) {
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.8",
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,112 @@
1
- # Organize user-supplied facts
1
+ # Expand supplied experience into strong resume content
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. Use a relevant role profile when it helps expose an ability already supported by the material; skip it for a straightforward wording or contact edit.
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 when a consequential ambiguity affects correctness or when a focused answer would materially improve the strongest evidence; otherwise deliver the supported draft. 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
+ ## Expand meaning, not the candidate's history
14
+
15
+ The Agent is an editor and reasoning partner. Do more than copy the input: organize scattered facts, resolve supplied relationships, explain what an action demonstrates, and make the strongest evidence easy to read. More words are useful only when they add supported meaning.
16
+
17
+ Distinguish three operations:
18
+
19
+ | Operation | Treatment |
20
+ | --- | --- |
21
+ | Professional expression | Freely improve sentence structure, terminology, grouping and emphasis while preserving meaning. |
22
+ | Supported ability synthesis | Name a bounded ability demonstrated by the described action. Implementing an API can support “API development experience”; it does not establish distributed architecture expertise. Avoid “expert”, “proficient” or broad mastery without corresponding input. |
23
+ | New historical detail | Ask or present it as an optional question outside the resume. Do not assert an unprovided implementation, business setting, ownership, scale, result or metric. |
24
+
25
+ Use any suitable writing pattern, leaving unsupported parts out:
26
+
27
+ - **Delivery:** supplied responsibility + object/module + supplied implementation or collaboration context.
28
+ - **Problem solving:** supplied problem + personal action + known mechanism + observed result, if available.
29
+ - **Technical practice:** supplied technology + actual use + demonstrated, bounded capability.
30
+ - **Transferable ability:** concrete action + underlying problem-solving ability relevant to the target, without relabeling the original stack.
31
+ - **Leadership:** actual decision/coordination scope + personal action + supplied outcome. Seniority and target titles do not supply leadership evidence.
32
+
33
+ Do not fill every slot or force every bullet into FAB. Split a dense description when it contains distinct contributions; combine fragments when they describe the same achievement. Skills should summarize practice at the supported level, not become a catalog of the role profile.
34
+
35
+ ### Examples: input → useful expansion
36
+
37
+ These examples illustrate reasoning, not reusable candidate facts.
38
+
39
+ - Input: “用 Node.js/NestJS 写了订单创建和状态查询接口。”
40
+ Resume: “基于 Node.js / NestJS 开发订单创建与状态查询接口。”
41
+ The input is already specific: a shorter sentence is better than adding “完成后端接口开发” to repeat it. Ability summary, if useful elsewhere: “具备 Node.js / NestJS 后端接口开发经验。” Prefer the concrete bullet when space is limited; do not repeat both mechanically. Do not add payment consistency, high concurrency or independent ownership.
42
+ - Input: “用 Python 做了内部文档问答,文档向量化后检索,再交给大模型回答。”
43
+ Resume: “使用 Python 实现内部文档问答,将文档向量化、相关内容检索与大模型回答生成串联为 RAG 问答流程。”
44
+ This names a mechanism the user actually described. It does not establish LangChain, a particular vector database, reranking, agent planning or production scale.
45
+ - Input: “参与 Redis 缓存开发,把热点商品信息放缓存,减少重复查数据库。”
46
+ Resume: “参与商品信息缓存开发,使用 Redis 缓存热点商品数据,减少重复数据库查询。”
47
+ Do not add cache-hit rate, distributed locks, cache penetration protection or a percentage improvement.
48
+ - Input: “做过 Agent,用过 LangGraph。”
49
+ Safe current version: “具有基于 LangGraph 的 Agent 开发经历。”
50
+ High-value question: “这个 Agent 完成什么任务?你实现了哪些节点、工具或流程?” Do not expand into multi-agent orchestration or autonomous planning without an answer.
51
+
52
+ ## Ask for information that changes the writing
53
+
54
+ Prefer a focused question about the strongest relevant experience: what problem, what personal contribution, what concrete method, what observable change? Select the missing dimension with the highest value; do not require a fixed interview sequence or numeric results. User feedback, completed delivery, reduced manual work or resolved failures can be useful outcomes when supplied.
55
+
56
+ If the user wants an immediate result, write the supported version now and optionally mention the most valuable missing detail. If the user wants deeper expansion, use their answer to strengthen the draft. Do not block usable content on optional details or put unconfirmed placeholders into the final resume. Ambiguous ownership or conflicting critical facts warrant clarification; routine phrasing does not require approval.
57
+
58
+ ## Concrete rewrite boundaries
59
+
60
+ These are isolated editing examples, not candidate material or a profile to execute.
61
+
62
+ | Supplied statement | Faithful treatment | Unsupported addition |
63
+ | --- | --- | --- |
64
+ | 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 |
65
+ | Participated in Redis and message-queue work | Keep “participated” and the unnamed message queue | Led architecture; Kafka/RocketMQ; cache prewarming; payment/event pipelines |
66
+ | 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 |
67
+ | 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 |
68
+ | Used Spring Boot and MySQL | List those technologies or the supplied use case | Expert JVM/JUC knowledge, deep index internals, distributed transactions |
69
+ | 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 |
70
+
71
+ 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.
72
+
73
+ ## Editorial review: make each sentence earn its place
74
+
75
+ Use these criteria to revise a substantive draft, not as a mandatory user-visible checklist or a fixed number of revision passes. Stop when the material is clear, useful and faithful; do not rewrite repeatedly for synonyms.
76
+
77
+ | Question | Editing action |
78
+ | --- | --- |
79
+ | What new information does the added phrase convey? | Remove restatements such as “开发接口,完成接口开发工作” and generic claims such as “展现优秀技术能力”. |
80
+ | Can a reader identify the candidate's action? | Prefer a concrete action and object to “深度赋能 / 全面推动 / 闭环落地”. Preserve the supplied ownership level. |
81
+ | Are method and result actually connected in the source? | Combine related facts, but do not attach a team's result to the candidate's action without support. |
82
+ | Does a number retain its meaning? | Preserve approximate qualifiers, measurement scope, baseline and time period when given. Do not turn average latency into P99 or a team result into a personal result. |
83
+ | Is the strongest evidence easy to find? | Put the most relevant contribution early within its entry. Keep job chronology legible rather than moving dates or mixing employers for keyword emphasis. |
84
+ | Is the summary doing different work from the detail? | Summarize a supported pattern of practice; leave its specific achievement in one primary location. Omit the summary when it only duplicates a short entry. |
85
+
86
+ ### Compose sections according to the available evidence
87
+
88
+ - **Summary:** optional, usually a compact statement of actual practice and distinctive scope. No invented years, self-ratings or promise of future impact. A target role belongs in the objective when it differs from actual experience.
89
+ - **Skills:** group supplied technologies by meaningful use where possible, such as “后端开发:Node.js / NestJS(订单接口)”. Mentioned-only tools may remain tools; do not add use cases or expertise. Avoid repeating every technology in both a long summary and multiple skill paragraphs.
90
+ - **Experience:** give useful context once, then distinct contributions. Do not manufacture a separate project from each duty. A named project inside an employer can be developed when the source supports its context and contribution.
91
+ - **Projects:** prioritize distinct supplied work. Preserve its nature: course exercise, personal prototype, internal tool and production service are different settings. Do not silently promote one into another.
92
+
93
+ Choose wording and section labels for the user's language. Preserve recognizable technology names; avoid literal translation of English action-verb formulas into inflated Chinese. Do not enforce an English word-count target on Chinese summaries. Sparse material may justify a few polished bullets; rich material may justify fuller entries. Neither a fixed bullet count nor a full page is a content-quality target.
94
+
95
+ ### Rich input: organize distinct evidence rather than inflate it
96
+
97
+ Fictional source: “给内部客服做过 Python 文档问答。我的部分是把文档分段、向量化、检索,再把相关内容交给模型回答。还整理了 30 个常见问题,检查回答有没有文档依据,发现问题后调整分段。没有统计准确率。”
98
+
99
+ Possible resume entry:
100
+ - “参与内部客服文档问答开发,使用 Python 实现文档分段、向量化、检索与上下文组装,为模型回答提供相关文档内容。”
101
+ - “整理 30 个常见问题,检查回答的文档依据,并根据发现的问题调整文档分段。”
102
+
103
+ The two bullets show application implementation and evaluation practice. They do not claim automated evaluation, a specific retrieval library, accuracy improvement or ownership of the whole application. A separate summary is optional, not another copy of these bullets. Here “参与” reflects the explicitly limited personal scope; do not apply it to users who explicitly owned the whole project.
104
+
105
+ ## Continue safely across turns
106
+
107
+ - 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.
108
+ - 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.
109
+ - 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.
110
+ - 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.
111
+
112
+ 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.
@@ -4,21 +4,23 @@
4
4
 
5
5
  ---
6
6
 
7
- ## 1. Professional Seniority Signals
7
+ ## 1. Position from demonstrated scope
8
8
 
9
- Identify candidate level and calibrate narrative depth accordingly:
9
+ Use the user's actual responsibility and target to choose emphasis. Years and titles provide context, not proof of seniority. The same candidate may have strong implementation evidence but limited leadership evidence; express each at its supported level.
10
10
 
11
- | Seniority Tier | Core Value Proposition | Key Narrative Signals | Section Priority |
12
- |:---|:---|:---|:---|
13
- | **Junior (1~3 Years)** | Rapid learning, solid coding standards, reliable task delivery | Clean code, unit test coverage, framework fluency, bug resolution | Skills → Projects → Experience → Education |
14
- | **Mid-Level (3~5 Years)** | Independent ownership, feature architecture, performance optimization | End-to-end module ownership, database tuning, API design, CI/CD | Experience → Projects → Skills → Education |
15
- | **Senior / Lead (5~8+ Years)** | System architecture, technical leadership, cross-system trade-offs | Distributed systems, high availability, mentoring, business impact | Experience → Projects → Architecture → Skills |
16
- | **Principal / Architect** | Technical vision, organizational strategy, governance, ROI | Architecture governance, multi-team alignment, technology selection | Experience → Leadership → Architecture → Patents |
11
+ | Supplied evidence | Useful emphasis | Possible leading section |
12
+ | --- | --- | --- |
13
+ | Course, personal or internship projects | Concrete implementation and problem solving; preserve the project setting | Relevant projects or education |
14
+ | Delivered modules or features | Personal contribution, methods and actual delivery scope | Work experience |
15
+ | System decisions and cross-service trade-offs | What was decided, why, and the user's actual authority | Relevant work or projects |
16
+ | Team coordination or organizational responsibility | Actual coordination scope, decisions and observed outcomes | Work experience |
17
17
 
18
- ---
18
+ These are editorial options, not an automatic section order or a requirement to create “Architecture”, “Leadership” or “Patents” sections. Use the strongest supplied evidence first within a clear career narrative.
19
19
 
20
20
  ## 2. Role Archetypes Knowledge Base (`src/knowledge/roles/*.json`)
21
21
 
22
+ Read the relevant role profile when positioning or ability expansion would improve supplied candidate material. Treat its section order as a suggestion; demonstrated strengths and the target audience determine the actual hierarchy. `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
@@ -29,10 +31,30 @@ The skill ships with 9+ structured role profiles:
29
31
 
30
32
  ---
31
33
 
32
- ## 3. Core Value Proposition Formulation
34
+ ## 3. Write a useful summary when the evidence warrants one
35
+
36
+ Select a supported pattern of work plus a distinctive context or responsibility. Mention a result only when it adds information beyond the detailed entry. A short profile does not need a summary. Do not fill a formula with years, strengths and impact that the source does not provide.
37
+
38
+ Fictional source: “用 Python 做过内部文档问答,自己做了文档检索与模型回答衔接,也整理常见问题检查回答依据。”
39
+
40
+ Possible summary: “具有 Python 文档问答应用开发经验,实践覆盖检索与模型回答衔接、基于常见问题的回答检查。”
41
+
42
+ Detailed bullets should then supply the concrete implementation and checking work. This source does not justify “资深 Agent 架构师”, “端到端多智能体平台” or a quantified improvement. For a single short project, prefer its concrete bullets and omit this summary.
43
+
44
+ ## 4. Use role templates as reasoning aids
45
+
46
+ Choose one relevant role, then connect each promising `evidenceSignals` topic to an actual user action. Classify it as direct support, transferable support, or unknown. Develop only supported topics into resume prose. `mustHaveSkills` describes the archetype, not a universal hiring requirement or a personal qualification; a supplied JD and the candidate's facts take precedence.
47
+
48
+ For AI Agent engineering, consider the following angles only when the user describes related work:
49
+
50
+ | Supplied work | Ability that may be expressed | Detail worth asking about |
51
+ | --- | --- | --- |
52
+ | Implemented workflow nodes and branches | Workflow orchestration implementation | Actual state transitions and personal scope |
53
+ | Connected a model to external tools | Tool integration | Tool purpose, argument handling, failure behavior actually implemented |
54
+ | Retrieved documents for model answers | RAG application development | Retrieval steps, corpus, evaluation if performed |
55
+ | Compared answers against a test set | Model/application evaluation practice | Evaluation criteria and observed findings |
56
+ | Deployed and maintained an application | Application delivery and maintenance | Actual users, operational responsibility, observed issues |
33
57
 
34
- Synthesize the 15~25 word Value Proposition headline following this formula:
35
- $$\text{Value Proposition} = [\text{Target Role}] + [\text{Years/Domain Focus}] + [\text{Top 2 Signature Strengths}] + [\text{Concrete Impact Deliverable}]$$
58
+ These angles do not require all candidates to have all five capabilities. A simple LLM API application need not be promoted into a multi-agent system. Use the same method for frontend, backend, product and other roles: domain knowledge helps interpret actual work, not manufacture experience.
36
59
 
37
- *Example*:
38
- > **Senior AI Agent Engineer** with 5+ years building scalable LLM orchestration & enterprise RAG pipelines, delivering 40% latency reduction across multi-agent production workflows.
60
+ For a transition, show the original stack honestly and foreground reusable problem-solving evidence. A role objective may name the destination; actual job titles and historical projects retain their identities. For experienced candidates with strong work evidence, place that evidence before a long skills catalog; for students, relevant projects or education may lead.
@@ -11,6 +11,8 @@ Execute the JD analyzer to extract structured requirements:
11
11
  python3 scripts/evidence/analyze-jd.py --jd "path/to/jd.md" --json
12
12
  ```
13
13
 
14
+ The analyzer is a heuristic helper, not a semantic certification. `detectedSkills` lists recognized technologies, including those adjacent to Chinese text. `mustHaveSkills` and `niceToHaveSkills` classify explicit requirement markers or headings only; unclassified and conflicting skills remain in `detectedSkills` without being assigned a priority. Inspect the original JD before making a positioning decision.
15
+
14
16
  ### Signal Extraction Dimensions:
15
17
  1. **Target Role & Seniority Tier**: Extracted from title and years of experience requirements;
16
18
  2. **Must-Have Skills (Hard Constraints)**: Top technical stacks and non-negotiable architectural competencies;
@@ -21,24 +23,20 @@ python3 scripts/evidence/analyze-jd.py --jd "path/to/jd.md" --json
21
23
 
22
24
  ## 2. Keyword Density & Highlighting Rules
23
25
 
24
- In `workspace/resume.html`, inject JD keywords to pass ATS automated screening while remaining natural for human reviewers:
26
+ 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
27
 
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.
28
+ 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
29
 
30
- ---
30
+ ## 3. Writing useful bullets
31
31
 
32
- ## 3. FAB (Feature-Advantage-Benefit) Bullet Engineering
32
+ 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.
33
33
 
34
- Structure every project bullet point using the FAB formula:
34
+ 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.
35
35
 
36
- ```
37
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
38
- │ Feature (技术动作)│ ────> │ Advantage (技术优势)│ ────> │ Benefit (业务价值) │
39
- │ Exact tech & tool │ │ Architectural gain│ │ Quantified impact│
40
- └─────────────────┘ └─────────────────┘ └─────────────────┘
41
- ```
36
+ ## 4. Tailor the argument, not just the keywords
37
+
38
+ Before rendering, form an internal mapping: requirement → supplied experience → direct/transferable/unsupported → placement or question. This need not become a saved artifact. Read the original JD for scope, seniority and business problems; the heuristic parser cannot establish those meanings reliably.
39
+
40
+ Choose the strongest supported evidence for the most relevant requirements. Reorder bullets within entries, expand a relevant terse contribution, and compress repetition or less relevant detail while preserving useful chronology. A gap remains a gap; do not compensate by adding a skill list copied from the JD. Without a JD, use the user's target and an appropriate role archetype as a provisional editorial lens, not as a specific employer's requirements.
42
41
 
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**).
42
+ Check whether the tailored version actually changes the emphasis and evidence selection. Changing only the target title or bolding keywords is insufficient when the user asked for substantive tailoring. The pipeline's `--jd` option supplies search/highlighting hints; semantic tailoring is the host Agent's responsibility before submitting the profile.
@@ -1,43 +1,35 @@
1
- # Reference Manual 04: Template Selection & Layout Geometries
1
+ # Template selection and readable composition
2
+
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 thirteen current IDs below are directory IDs accepted by the pipeline; metadata describes design intent, not visual or ATS certification.
4
+
5
+ | ID | Structure | Review before choosing |
6
+ | --- | --- | --- |
7
+ | editorial | Single column with section rail | Experience first; medium-length professional histories |
8
+ | graduate | Single column, education first | Students and internships; preserve actual project setting |
9
+ | project-focus | Single column, projects first | Distinct project evidence; do not duplicate employment bullets |
10
+ | minimal | Single column | Straight reading order; sparse content needs breathing room rather than compression |
11
+ | international-flow | Single column | Consider for linear prose; inspect language and line lengths |
12
+ | modern | Sidebar, 32:68 | Keep side content short; check narrow-column wrapping |
13
+ | creative-tech | Sidebar, 28:72 | Use only when the visual emphasis suits the user |
14
+ | data-analyst | Sidebar, 30:70 | Do not invent metrics to match the template name |
15
+ | executive | Banner and split columns | Needs suitable supplied leadership evidence; a title does not confer it |
16
+ | classic | Structured table | Check sparse fields and reading order |
17
+ | compact-dense | Dense two columns | For substantial supplied content; avoid for a short career description |
18
+ | academic-research | Dense single column | Research content must actually be supplied |
19
+ | startup-generalist | Modular cards | Check block balance with the actual sections |
20
+
21
+ Use the existing search when no template was selected:
2
22
 
3
- > **"Layout geometry determines information hierarchy. Select the composition that earns the candidate's strongest evidence."**
4
-
5
- ---
6
-
7
- ## 1. Core Template Matrix (Baseline 4)
8
-
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
23
  ```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
24
+ python3 <skill-root>/scripts/template/search-template.py "<target role>" --target-pages 1 --summary
30
25
  ```
31
26
 
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)$$
27
+ 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.
34
28
 
35
- ---
29
+ 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 designs were visually compared if only one was rendered.
36
30
 
37
- ## 3. Instantiating the Intermediate HTML Canvas
31
+ 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.
38
32
 
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
- ```
33
+ 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.
42
34
 
43
- *The instantiator automatically inlines `src/templates/common/base.css` + `src/templates/{template}/style.css` into a single self-contained HTML file.*
35
+ Choose one suitable layout from metadata before production; search results are suggestions, not a queue of templates to render. Compare multiple rendered alternatives only on request or to address a concrete visual defect. Keep experiments outside the candidate directory. A successful current output already exists at the delivery paths; do not run the same input/layout again solely to publish another copy.
@@ -2,11 +2,13 @@
2
2
 
3
3
  Instantiate an empty canvas.html skeleton with explicit user facts. canvas.html is the sole maintained structure. Gallery previews bind explicit fictional sample-profile.json through the same instantiator and full CSS chain; sample data must never serve as default candidate facts. Shared normalization accepts omitted/null optional fields and rejects invalid types. Failed binding must preserve old output and return nonzero.
4
4
 
5
- Tune the run's HTML with CSS variables for section/item/bullet spacing and body typography. Preserve manually edited content rather than regenerating stale profile data. Auto-healing cannot remove facts or reduce body font below 8.8pt. Validate in print mode, inspect all pages and verify the actual PDF before delivery. See 07-artifact-contract.md.
5
+ Read the current delivery HTML and tune it in memory with CSS variables for section/item/bullet spacing and body typography. Preserve manually edited content rather than regenerating stale profile data. Auto-healing cannot remove facts or reduce body font below 8.8pt. Validate in print mode, inspect all pages and verify the actual PDF before delivery. Submit the complete edited HTML via `forge.py --html-input -`, using the current delivery paths; do not save an unverified edit over the accepted HTML. See 07-artifact-contract.md.
6
6
 
7
7
 
8
8
  ## 本地字体与缺字诊断
9
9
 
10
- `forge.py` 和 `instantiate-resume.py` 支持 `--font-preset system|arial-unicode`,默认保留系统字体。`arial-unicode` 显式使用本机 Arial Unicode MS;没有该字体时字体验收失败并返回 UNVERIFIED,不保证跨机器可用,也不自动下载字体。字体选择只改变画布样式,不改变 Master 事实,并记录在 Variant 的 source.fontPreset 和运行清单中。
10
+ `forge.py --profile-json` 和 `instantiate-resume.py` 支持 `--font-preset system|arial-unicode`,默认保留系统字体。`arial-unicode` 显式使用本机 Arial Unicode MS;没有该字体时字体验收失败并返回 UNVERIFIED,不保证跨机器可用,也不自动下载字体。字体选择只改变画布样式,不改变 Master 事实,并记录在 Variant 的 source.fontPreset 和运行清单中。
11
+
12
+ `--html-input` 保留已有字体,不接受字体预设覆盖;需要更换字体时修改内存中的画布 CSS,再通过相同入口验收。
11
13
 
12
14
  中文 PDF 若文本验收失败,检查 QA 每页的 missingCodepoints、missingFragments 与 extractedRadicals。部首字符可能来自字体字码映射差异,也可能存在真实缺字;不能仅凭这种提示放行。可选用本机可用字体、创建新运行并重新检查,不改写姓名/经历来绕过问题,也不把部首字符全部忽略。