Skip to content

Commit 1171962

Browse files
authored
Merge pull request #79 from RajjjAryan/fix/audit-followups-batch-2
Fix system contract drift and default mode language
2 parents c3d6abe + 99b60ab commit 1171962

10 files changed

Lines changed: 466 additions & 298 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Dependencies
22
node_modules/
3+
.venv/
4+
venv/
5+
env/
36

47
# Output (generated, user-specific)
58
output/*

DATA_CONTRACT.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ These files belong to the user. The AI agent reads them for context but **never
1313
| `modes/_profile.md` | Personal profile overrides (created from template) |
1414
| `article-digest.md` | Proof points from portfolio projects/articles |
1515
| `portals.yml` | Scanner configuration (copied from template) |
16+
| `feeds.yml` | RSS/Atom feed scanner configuration (copied from template) |
1617
| `data/applications.md` | Application tracker (modified only via merge-tracker) |
1718
| `data/pipeline.md` | URL inbox for pending evaluations |
19+
| `jds/*` | Saved private job descriptions |
1820
| `reports/*` | Evaluation reports (generated, then user-owned) |
1921
| `output/*` | Generated PDFs (generated, then user-owned) |
2022
| `interview-prep/*` | Story bank and interview prep files |
23+
| `batch/tracker-additions/*` | Temporary tracker rows generated before merge |
2124

2225
## System Layer — safe for automated updates
2326

@@ -26,13 +29,23 @@ These files are part of the pipeline infrastructure. They can be updated by cont
2629
| File | Purpose |
2730
|------|---------|
2831
| `.github/copilot-instructions.md` | Main agent instruction set |
32+
| `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `.windsurfrules` | AI tool entry points |
33+
| `.github/`, `.vscode/mcp.json` | GitHub metadata, templates, CI, and MCP configuration |
2934
| `modes/_shared.md` | Shared scoring rules, archetypes, tool references |
3035
| `modes/*.md` (except `_profile.md`) | Skill mode definitions |
36+
| `modes/{de,es,fr,hi,ja,pt}/` | Localized mode packs |
3137
| `templates/cv-template.html` | ATS-optimized CV HTML template |
3238
| `templates/states.yml` | Canonical application statuses |
3339
| `templates/portals.example.yml` | Portal scanner template |
40+
| `templates/feeds.example.yml` | Feed scanner template |
41+
| `templates/cv-i18n.yml` | Localized CV section labels |
3442
| `config/profile.example.yml` | Profile template |
3543
| `*.mjs` scripts | Utility scripts |
44+
| `lib/**` | Shared script modules and adapters |
45+
| `tests/**` | Regression and contract tests |
46+
| `dashboard/**` | Terminal and web dashboard source |
47+
| `examples/*` | Safe sample inputs and reports |
48+
| `docs/assets/*`, named docs in `docs/` | System documentation and launch assets |
3649
| `batch/batch-prompt.md` | Self-contained batch worker prompt |
3750
| `generate-pdf.mjs` | HTML → PDF generation |
3851

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ career-copilot/
207207
│ ├── patterns.md # Outcome and role-fit pattern analysis
208208
│ ├── training.md # Course/cert evaluation
209209
│ ├── project.md # Portfolio project evaluation
210-
│ └── hi/, de/, fr/, pt/ # Localized mode packs
210+
│ └── de/, es/, fr/, hi/, ja/, pt/ # Localized mode packs
211211
├── config/
212212
│ └── profile.example.yml # Profile template
213213
├── templates/

modes/pdf.md

Lines changed: 151 additions & 149 deletions
Large diffs are not rendered by default.

modes/scan.md

Lines changed: 147 additions & 146 deletions
Large diffs are not rendered by default.

templates/cv-i18n.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ de:
1616
certifications: "Zertifizierungen"
1717
skills: "Kenntnisse"
1818

19+
es:
20+
summary: "Resumen Profesional"
21+
competencies: "Competencias Clave"
22+
experience: "Experiencia Profesional"
23+
projects: "Proyectos"
24+
education: "Formacion"
25+
certifications: "Certificaciones"
26+
skills: "Habilidades"
27+
1928
fr:
2029
summary: "Profil Professionnel"
2130
competencies: "Competences Cles"
@@ -42,3 +51,12 @@ hi:
4251
education: "शिक्षा"
4352
certifications: "प्रमाणपत्र"
4453
skills: "कौशल"
54+
55+
ja:
56+
summary: "職務要約"
57+
competencies: "主要スキル"
58+
experience: "職務経歴"
59+
projects: "プロジェクト"
60+
education: "学歴"
61+
certifications: "資格"
62+
skills: "スキル"

tests/cv-i18n.test.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { getCvLabels } from '../lib/cv-i18n.mjs';
55

66
test('returns localized CV section labels with English fallback', () => {
77
assert.equal(getCvLabels('de').experience, 'Berufserfahrung');
8+
assert.equal(getCvLabels('es').summary, 'Resumen Profesional');
89
assert.equal(getCvLabels('fr').skills, 'Competences');
10+
assert.equal(getCvLabels('ja').experience, '職務経歴');
911
assert.equal(getCvLabels('unknown').experience, 'Experience');
1012
});

tests/feature-entrypoints.test.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ test('PDF import and feed support have scripts, templates, and npm commands', ()
2828

2929
test('CV i18n template exists and documents supported locales', () => {
3030
const content = readFileSync(path('templates', 'cv-i18n.yml'), 'utf-8');
31-
for (const locale of ['en:', 'de:', 'fr:', 'pt:', 'hi:']) {
31+
for (const locale of ['en:', 'de:', 'es:', 'fr:', 'hi:', 'ja:', 'pt:']) {
3232
assert.match(content, new RegExp(`^${locale}`, 'm'));
3333
}
3434
});

tests/repo-contract.test.mjs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
import test from 'node:test';
22
import assert from 'node:assert/strict';
3+
import { execSync } from 'node:child_process';
34
import { existsSync, readdirSync, readFileSync } from 'node:fs';
45
import { join } from 'node:path';
56

67
const root = new URL('..', import.meta.url);
78
const path = (...parts) => join(root.pathname, ...parts);
89

10+
function gitLsFiles() {
11+
return execSync('git ls-files', { cwd: root.pathname, encoding: 'utf-8' }).trim().split('\n').filter(Boolean);
12+
}
13+
14+
function readSystemPaths() {
15+
const updater = readFileSync(path('update-system.mjs'), 'utf-8');
16+
const match = updater.match(/const SYSTEM_PATHS = \[([\s\S]*?)\];/);
17+
assert.ok(match, 'SYSTEM_PATHS should be defined in update-system.mjs');
18+
return [...match[1].matchAll(/'([^']+)'/g)].map((item) => item[1]);
19+
}
20+
921
test('user-facing setup docs contain copy-pasteable clone commands', () => {
1022
for (const file of ['README.md', 'docs/SETUP.md']) {
1123
const content = readFileSync(path(file), 'utf-8');
@@ -20,6 +32,9 @@ test('README project map stays aligned with shipped workflow families', () => {
2032
for (const shippedItem of ['analytics.md', 'feed-scan.md', 'negotiate.md', 'equity.md', 'import-cv.mjs']) {
2133
assert.match(readme, new RegExp(shippedItem.replace('.', '\\.')), `${shippedItem} should be visible in README`);
2234
}
35+
for (const localeDir of ['de/', 'es/', 'fr/', 'hi/', 'ja/', 'pt/']) {
36+
assert.match(readme, new RegExp(localeDir.replace('/', '\\/')), `${localeDir} should be visible in README`);
37+
}
2338
});
2439

2540
test('README includes GitHub-renderable demo and adoption links', () => {
@@ -63,6 +78,89 @@ test('system updater uses explicit docs paths', () => {
6378
}
6479
});
6580

81+
test('system updater covers every tracked system file', () => {
82+
const systemPaths = readSystemPaths();
83+
const userExact = new Set([
84+
'article-digest.md',
85+
'config/profile.yml',
86+
'cv.md',
87+
'feeds.yml',
88+
'modes/_profile.md',
89+
'portals.yml',
90+
]);
91+
const userPrefixes = [
92+
'batch/logs/',
93+
'batch/tracker-additions/',
94+
'data/',
95+
'interview-prep/',
96+
'jds/',
97+
'output/',
98+
'reports/',
99+
];
100+
const generatedExact = new Set(['dashboard/dashboard']);
101+
102+
const isCovered = (file) => systemPaths.some((entry) => (
103+
entry.endsWith('/') ? file.startsWith(entry) : file === entry
104+
));
105+
106+
const missing = gitLsFiles().filter((file) => (
107+
!userExact.has(file) &&
108+
!generatedExact.has(file) &&
109+
!userPrefixes.some((prefix) => file.startsWith(prefix)) &&
110+
!isCovered(file)
111+
));
112+
113+
assert.deepEqual(missing, []);
114+
});
115+
116+
test('data contract documents current user and system boundaries', () => {
117+
const contract = readFileSync(path('DATA_CONTRACT.md'), 'utf-8');
118+
119+
for (const userPath of ['feeds.yml', 'jds/*', 'batch/tracker-additions/*']) {
120+
assert.match(contract, new RegExp(userPath.replaceAll('*', '\\*')), `${userPath} should be documented as user-layer data`);
121+
}
122+
123+
for (const systemPath of [
124+
'lib/**',
125+
'tests/**',
126+
'templates/feeds.example.yml',
127+
'templates/cv-i18n.yml',
128+
'docs/assets/*',
129+
'examples/*',
130+
'modes/{de,es,fr,hi,ja,pt}/',
131+
]) {
132+
assert.match(contract, new RegExp(systemPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')), `${systemPath} should be documented as system-layer data`);
133+
}
134+
});
135+
136+
test('root-level English modes do not contain known Spanish instruction leakage', () => {
137+
const rootModeFiles = readdirSync(path('modes')).filter((file) => file.endsWith('.md') && !file.startsWith('_'));
138+
const leakedPhrases = [
139+
'Modo:',
140+
'Configuración',
141+
'Ejecución recomendada',
142+
'Leer `portals.yml`',
143+
'Idiomas soportados',
144+
'Usar el template',
145+
'Post-generación',
146+
'Para cada empresa',
147+
];
148+
149+
for (const file of rootModeFiles) {
150+
const content = readFileSync(path('modes', file), 'utf-8');
151+
for (const phrase of leakedPhrases) {
152+
assert.equal(content.includes(phrase), false, `${file} should not contain Spanish phrase: ${phrase}`);
153+
}
154+
}
155+
});
156+
157+
test('root gitignore covers common Python virtual environments', () => {
158+
const gitignore = readFileSync(path('.gitignore'), 'utf-8');
159+
for (const entry of ['.venv/', 'venv/', 'env/']) {
160+
assert.match(gitignore, new RegExp(`^${entry.replace('.', '\\.').replace('/', '\\/')}$`, 'm'), `${entry} should be ignored`);
161+
}
162+
});
163+
66164
test('mode files use canonical user-layer paths', () => {
67165
const modeDir = path('modes');
68166
const modeFiles = readdirSync(modeDir).filter((file) => file.endsWith('.md'));

update-system.mjs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,52 @@ const SYSTEM_PATHS = [
5050
'modes/training.md',
5151
'modes/interview-prep.md',
5252
'modes/patterns.md',
53+
'modes/auto-apply.md',
5354
'modes/de/',
55+
'modes/es/',
5456
'modes/fr/',
55-
'modes/pt/',
5657
'modes/hi/',
58+
'modes/ja/',
59+
'modes/pt/',
60+
'.cursorrules',
61+
'.gitignore',
62+
'.github/',
5763
'.github/copilot-instructions.md',
64+
'.vscode/mcp.json',
65+
'.windsurfrules',
5866
'AGENTS.md',
67+
'CLAUDE.md',
68+
'CODE_OF_CONDUCT.md',
69+
'GEMINI.md',
70+
'INSTRUCTIONS.md',
71+
'LEGAL_DISCLAIMER.md',
5972
'generate-pdf.mjs',
6073
'analytics.mjs',
74+
'analyze-patterns.mjs',
75+
'apply-jobs.mjs',
76+
'check-liveness.mjs',
6177
'feed-scan.mjs',
6278
'import-cv.mjs',
79+
'doctor.mjs',
80+
'extract-resume.py',
6381
'merge-tracker.mjs',
6482
'verify-pipeline.mjs',
6583
'dedup-tracker.mjs',
6684
'normalize-statuses.mjs',
6785
'cv-sync-check.mjs',
86+
'setup-cli.mjs',
87+
'setup.sh',
88+
'tailor-resume.mjs',
89+
'telegram-bot.mjs',
90+
'test-all.mjs',
6891
'update-system.mjs',
6992
'batch/batch-prompt.md',
7093
'batch/batch-runner.sh',
94+
'config/profile.example.yml',
7195
'dashboard/',
96+
'examples/',
97+
'lib/',
98+
'tests/',
7299
'templates/',
73100
'fonts/',
74101
'.github/skills/',
@@ -81,13 +108,17 @@ const SYSTEM_PATHS = [
81108
'docs/assets/social-preview.svg',
82109
'docs/demo.cast',
83110
'docs/evaluation-walkthrough.md',
111+
'docs/plans/2026-04-14-auto-apply-latex-fixes.md',
112+
'docs/specs/2026-04-14-auto-apply-design.md',
84113
'VERSION',
85114
'DATA_CONTRACT.md',
86115
'CONTRIBUTING.md',
87116
'README.md',
88117
'LICENSE',
89118
'CITATION.cff',
119+
'package-lock.json',
90120
'package.json',
121+
'requirements.txt',
91122
];
92123

93124
// User layer paths — NEVER touch these (safety check)

0 commit comments

Comments
 (0)