@forwardimpact/outpost 3.0.3

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 (120) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +15 -0
  3. package/bin/fit-outpost.js +3 -0
  4. package/config/scheduler.json +34 -0
  5. package/package.json +63 -0
  6. package/src/agent-runner.js +189 -0
  7. package/src/index.js +5 -0
  8. package/src/kb-manager.js +228 -0
  9. package/src/outpost.js +417 -0
  10. package/src/scheduler.js +195 -0
  11. package/src/socket-server.js +336 -0
  12. package/src/state-manager.js +126 -0
  13. package/templates/.claude/agents/chief-of-staff.md +58 -0
  14. package/templates/.claude/agents/concierge.md +46 -0
  15. package/templates/.claude/agents/head-hunter.md +57 -0
  16. package/templates/.claude/agents/librarian.md +60 -0
  17. package/templates/.claude/agents/postman.md +47 -0
  18. package/templates/.claude/agents/recruiter.md +63 -0
  19. package/templates/.claude/settings.json +88 -0
  20. package/templates/.claude/skills/candidate-report/SKILL.md +139 -0
  21. package/templates/.claude/skills/candidate-report/references/report-template.html +203 -0
  22. package/templates/.claude/skills/candidate-report/references/report.css +438 -0
  23. package/templates/.claude/skills/candidate-report/references/rubric.md +76 -0
  24. package/templates/.claude/skills/candidate-report/scripts/render-pdf.mjs +48 -0
  25. package/templates/.claude/skills/deck-create/SKILL.md +75 -0
  26. package/templates/.claude/skills/deck-create/references/slide.css +35 -0
  27. package/templates/.claude/skills/deck-create/scripts/convert-to-pdf.mjs +47 -0
  28. package/templates/.claude/skills/deck-summarize/SKILL.md +139 -0
  29. package/templates/.claude/skills/deck-summarize/references/brief-template.md +85 -0
  30. package/templates/.claude/skills/deck-summarize/scripts/extract-pptx.mjs +210 -0
  31. package/templates/.claude/skills/doc-collab/SKILL.md +112 -0
  32. package/templates/.claude/skills/doc-create/SKILL.md +105 -0
  33. package/templates/.claude/skills/doc-create/scripts/convert-to-pdf.mjs +50 -0
  34. package/templates/.claude/skills/draft-emails/SKILL.md +141 -0
  35. package/templates/.claude/skills/draft-emails/references/template.md +26 -0
  36. package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +66 -0
  37. package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +139 -0
  38. package/templates/.claude/skills/extract-entities/SKILL.md +187 -0
  39. package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +14 -0
  40. package/templates/.claude/skills/extract-entities/references/conditions.md +55 -0
  41. package/templates/.claude/skills/extract-entities/references/content.md +104 -0
  42. package/templates/.claude/skills/extract-entities/references/links.md +48 -0
  43. package/templates/.claude/skills/extract-entities/references/recruitment.md +57 -0
  44. package/templates/.claude/skills/extract-entities/references/resolution.md +71 -0
  45. package/templates/.claude/skills/extract-entities/references/sources.md +70 -0
  46. package/templates/.claude/skills/extract-entities/references/templates-conditions.md +36 -0
  47. package/templates/.claude/skills/extract-entities/references/templates-goals-priorities.md +63 -0
  48. package/templates/.claude/skills/extract-entities/references/templates-people-orgs.md +67 -0
  49. package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +68 -0
  50. package/templates/.claude/skills/extract-entities/scripts/state.mjs +131 -0
  51. package/templates/.claude/skills/hyprnote-follow/SKILL.md +174 -0
  52. package/templates/.claude/skills/hyprnote-follow/references/coaching.md +118 -0
  53. package/templates/.claude/skills/hyprnote-follow/references/debrief.md +59 -0
  54. package/templates/.claude/skills/hyprnote-follow/references/meeting-types.md +14 -0
  55. package/templates/.claude/skills/hyprnote-follow/scripts/follow.mjs +243 -0
  56. package/templates/.claude/skills/hyprnote-process/SKILL.md +147 -0
  57. package/templates/.claude/skills/hyprnote-process/references/extraction.md +84 -0
  58. package/templates/.claude/skills/hyprnote-process/references/sessions.md +81 -0
  59. package/templates/.claude/skills/hyprnote-process/scripts/scan.mjs +246 -0
  60. package/templates/.claude/skills/hyprnote-trim/SKILL.md +177 -0
  61. package/templates/.claude/skills/manage-tasks/SKILL.md +152 -0
  62. package/templates/.claude/skills/manage-tasks/references/format.md +73 -0
  63. package/templates/.claude/skills/meeting-prep/SKILL.md +180 -0
  64. package/templates/.claude/skills/organize-files/SKILL.md +146 -0
  65. package/templates/.claude/skills/organize-files/scripts/organize-by-type.mjs +105 -0
  66. package/templates/.claude/skills/organize-files/scripts/summarize.mjs +91 -0
  67. package/templates/.claude/skills/req-assess/SKILL.md +137 -0
  68. package/templates/.claude/skills/req-assess/references/interview-template.md +62 -0
  69. package/templates/.claude/skills/req-assess/references/panel-template.md +117 -0
  70. package/templates/.claude/skills/req-assess/references/rubric.md +65 -0
  71. package/templates/.claude/skills/req-decide/SKILL.md +163 -0
  72. package/templates/.claude/skills/req-decide/references/rubric.md +63 -0
  73. package/templates/.claude/skills/req-decide/references/template.md +118 -0
  74. package/templates/.claude/skills/req-forget/SKILL.md +154 -0
  75. package/templates/.claude/skills/req-forget/references/classify.md +23 -0
  76. package/templates/.claude/skills/req-forget/references/locations.md +59 -0
  77. package/templates/.claude/skills/req-forget/references/report-template.md +67 -0
  78. package/templates/.claude/skills/req-scan/SKILL.md +145 -0
  79. package/templates/.claude/skills/req-scan/references/fallbacks.md +76 -0
  80. package/templates/.claude/skills/req-scan/references/filters.md +83 -0
  81. package/templates/.claude/skills/req-scan/references/sources.md +76 -0
  82. package/templates/.claude/skills/req-scan/references/state.md +54 -0
  83. package/templates/.claude/skills/req-scan/references/template.md +36 -0
  84. package/templates/.claude/skills/req-scan/scripts/state.mjs +396 -0
  85. package/templates/.claude/skills/req-screen/SKILL.md +151 -0
  86. package/templates/.claude/skills/req-screen/references/rubric.md +94 -0
  87. package/templates/.claude/skills/req-screen/references/template.md +91 -0
  88. package/templates/.claude/skills/req-track/SKILL.md +189 -0
  89. package/templates/.claude/skills/req-track/references/fields.md +114 -0
  90. package/templates/.claude/skills/req-track/references/signals.md +42 -0
  91. package/templates/.claude/skills/req-track/references/statuses.md +32 -0
  92. package/templates/.claude/skills/req-track/references/templates.md +127 -0
  93. package/templates/.claude/skills/req-workday/SKILL.md +162 -0
  94. package/templates/.claude/skills/req-workday/references/field-mapping.md +40 -0
  95. package/templates/.claude/skills/req-workday/references/status-mapping.md +38 -0
  96. package/templates/.claude/skills/req-workday/references/templates.md +126 -0
  97. package/templates/.claude/skills/req-workday/references/xlsx-format.md +56 -0
  98. package/templates/.claude/skills/req-workday/scripts/parse-workday.mjs +313 -0
  99. package/templates/.claude/skills/send-chat/SKILL.md +170 -0
  100. package/templates/.claude/skills/sync-apple-calendar/SKILL.md +145 -0
  101. package/templates/.claude/skills/sync-apple-calendar/references/SCHEMA.md +80 -0
  102. package/templates/.claude/skills/sync-apple-calendar/scripts/query.mjs +307 -0
  103. package/templates/.claude/skills/sync-apple-calendar/scripts/sync.mjs +332 -0
  104. package/templates/.claude/skills/sync-apple-mail/SKILL.md +151 -0
  105. package/templates/.claude/skills/sync-apple-mail/references/SCHEMA.md +115 -0
  106. package/templates/.claude/skills/sync-apple-mail/scripts/parse-emlx.mjs +389 -0
  107. package/templates/.claude/skills/sync-apple-mail/scripts/sync-helpers.mjs +372 -0
  108. package/templates/.claude/skills/sync-apple-mail/scripts/sync.mjs +239 -0
  109. package/templates/.claude/skills/sync-teams/SKILL.md +177 -0
  110. package/templates/.claude/skills/sync-teams/scripts/idb-reader.mjs +147 -0
  111. package/templates/.claude/skills/sync-teams/scripts/leveldb-reader.mjs +288 -0
  112. package/templates/.claude/skills/sync-teams/scripts/sync.mjs +381 -0
  113. package/templates/.claude/skills/upstream-skill/SKILL.md +130 -0
  114. package/templates/.claude/skills/upstream-skill/references/examples.md +80 -0
  115. package/templates/.claude/skills/weekly-update/SKILL.md +141 -0
  116. package/templates/.claude/skills/weekly-update/references/template.md +55 -0
  117. package/templates/CLAUDE.md +134 -0
  118. package/templates/USER.md +3 -0
  119. package/templates/apm.yml +5 -0
  120. package/templates/knowledge/Briefings/.gitkeep +0 -0
@@ -0,0 +1,203 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Candidate Report — {{CANDIDATE_NAME}}</title>
6
+ <!--
7
+ candidate-report template
8
+ ─────────────────────────
9
+ This is the structural skeleton for the A4 one-page candidate assessment.
10
+ Replace all {{PLACEHOLDER}} tokens with candidate-specific data.
11
+
12
+ The stylesheet is in references/report.css — inline it here with a <style>
13
+ tag (required for PDF rendering).
14
+
15
+ LAYOUT BUDGET (fits 297mm A4 height):
16
+ Header: ~60px
17
+ Verdict: ~36px
18
+ Body: ~680px (6 sections at ~110px avg)
19
+ Footer: ~28px
20
+
21
+ When customising, test with Ctrl+P (print preview) in a browser to verify
22
+ the report fits on a single page. If content overflows, reduce the number
23
+ of benchmark skills shown or shorten the strengths list.
24
+ -->
25
+ <style>
26
+ {{INLINE_CSS}}
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <!-- ── Header ── -->
31
+ <div class="hdr">
32
+ <div class="hdr-left">
33
+ <h1>{{CANDIDATE_NAME}}</h1>
34
+ <p>
35
+ {{CANDIDATE_TITLE}} &mdash; {{CANDIDATE_ORG}} &bull;
36
+ {{CANDIDATE_LOCATION}}
37
+ </p>
38
+ </div>
39
+ <div class="hdr-right">
40
+ {{REPORT_DATE}}<br />
41
+ {{TARGET_POD_OR_TEAM}}<br />
42
+ {{TARGET_DOMAIN}}
43
+ </div>
44
+ </div>
45
+
46
+ <!-- ── Verdict Banner ──
47
+ Classes: verdict-caution (amber), verdict-pass (red), verdict-proceed (green)
48
+ -->
49
+ <div class="verdict {{VERDICT_CLASS}}">
50
+ <strong>{{VERDICT_ICON}} {{VERDICT_HEADLINE}}</strong>
51
+ <span>&mdash; {{VERDICT_DETAIL}}</span>
52
+ </div>
53
+
54
+ <div class="body">
55
+ <!-- ── Row 1: Snapshot + Strengths (two columns) ── -->
56
+ <div class="cols">
57
+ <div class="col">
58
+ <div class="stitle">Snapshot</div>
59
+ <dl class="snap">
60
+ <!--
61
+ Typical fields: Experience, Education, Source, Stack.
62
+ Add/remove <dt>/<dd> pairs as needed for the candidate.
63
+ -->
64
+ {{SNAPSHOT_DL_ITEMS}}
65
+ </dl>
66
+ </div>
67
+ <div class="col">
68
+ <div class="stitle">Key Strengths</div>
69
+ <ul class="str-list">
70
+ <!--
71
+ 3-5 bullet points. Each: <li><strong>Label.</strong> Detail.</li>
72
+ -->
73
+ {{STRENGTHS_LI_ITEMS}}
74
+ </ul>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- ── Row 2: Level Gauge ── -->
79
+ <div>
80
+ <div class="stitle">
81
+ Level Calibration &mdash; estimated {{ESTIMATED_LEVEL}} vs target
82
+ {{TARGET_LEVEL}}
83
+ </div>
84
+ <div class="gauge">
85
+ <!--
86
+ Render one <div> per level on the gauge.
87
+ Add class="cand" to the estimated level, class="tgt" to the target.
88
+ Show 5 levels centred around the candidate/target range.
89
+
90
+ Example:
91
+ <div>J050<small>Level I</small></div>
92
+ <div class="cand">J060<small>Candidate</small></div>
93
+ <div class="tgt">J070<small>Target</small></div>
94
+ <div>J080<small>Level IV</small></div>
95
+ <div>J090<small>Staff</small></div>
96
+ -->
97
+ {{GAUGE_DIVS}}
98
+ </div>
99
+ </div>
100
+
101
+ <!-- ── Row 3: Benchmark Grid (2×2) ── -->
102
+ <div>
103
+ <div class="stitle">
104
+ Benchmark vs {{TARGET_LEVEL_LABEL}} {{DISCIPLINE_LABEL}} &mdash;
105
+ {{TRACK_LABEL}} ({{TOTAL_SKILLS}} skills)
106
+ </div>
107
+ <div class="bm">
108
+ <!--
109
+ Four .bm-area blocks in a 2×2 grid. Each contains:
110
+ <h4>🚀 Area Name</h4>
111
+ <div class="bm-row">
112
+ <span class="bm-skill">Skill Name</span>
113
+ <span class="p p-g">Gap</span> ← or p-a / p-p / p-u
114
+ </div>
115
+
116
+ Group the framework's capability areas into 4 visual blocks.
117
+ If there are 6 capability areas, combine the smallest two.
118
+ Show only skills where evidence exists or the gap is notable —
119
+ aim for 4-6 rows per block to stay within A4 height.
120
+
121
+ Pill classes:
122
+ p-g = Gap (red)
123
+ p-a = Partial (amber)
124
+ p-p = Positive / Met (green)
125
+ p-u = Unknown (grey)
126
+ -->
127
+ {{BENCHMARK_AREAS}}
128
+ </div>
129
+ </div>
130
+
131
+ <!-- ── Row 4: Behaviours + Coverage Counters (two columns) ── -->
132
+ <div class="cols">
133
+ <div class="col">
134
+ <div class="stitle">Behaviours</div>
135
+ <div class="beh">
136
+ <!--
137
+ One .beh-item per behaviour. Bar fill width = evidence strength (0-100%).
138
+ Colour: var(--green) positive, var(--amber) partial, var(--red) gap,
139
+ var(--s300) unknown.
140
+
141
+ <div class="beh-item">
142
+ <div class="beh-name">Behaviour Name</div>
143
+ <div class="beh-bar"><div style="width:70%; background:var(--green);"></div></div>
144
+ <div class="beh-tag">Assessment — short note</div>
145
+ </div>
146
+ -->
147
+ {{BEHAVIOUR_ITEMS}}
148
+ </div>
149
+ </div>
150
+ <div class="col">
151
+ <div class="stitle">Coverage Summary</div>
152
+ <div class="counters">
153
+ <!--
154
+ Four counter boxes. Colours are fixed:
155
+ Gap: background:#FEE2E2 text:#991B1B
156
+ Partial: background:#FEF3C7 text:#92400E
157
+ Unknown: background:var(--s100) text:var(--s500)
158
+ Met: background:#D1FAE5 text:#065F46
159
+ -->
160
+ <div class="ctr" style="background: #fee2e2">
161
+ <div class="n" style="color: #991b1b">{{COUNT_GAP}}</div>
162
+ <div class="l" style="color: #991b1b">Gap</div>
163
+ </div>
164
+ <div class="ctr" style="background: #fef3c7">
165
+ <div class="n" style="color: #92400e">{{COUNT_PARTIAL}}</div>
166
+ <div class="l" style="color: #92400e">Partial</div>
167
+ </div>
168
+ <div class="ctr" style="background: var(--s100)">
169
+ <div class="n" style="color: var(--s500)">{{COUNT_UNKNOWN}}</div>
170
+ <div class="l" style="color: var(--s500)">Unknown</div>
171
+ </div>
172
+ <div class="ctr" style="background: #d1fae5">
173
+ <div class="n" style="color: #065f46">{{COUNT_MET}}</div>
174
+ <div class="l" style="color: #065f46">Met</div>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ <!-- ── Row 5: Recommendation ── -->
181
+ <div>
182
+ <div class="stitle">Recommendation</div>
183
+ <div class="reco">
184
+ <ol>
185
+ <!--
186
+ 2-4 numbered action items. Each:
187
+ <li><strong>Action.</strong> Detail explaining the step.</li>
188
+ -->
189
+ {{RECOMMENDATION_LI_ITEMS}}
190
+ </ol>
191
+ </div>
192
+ </div>
193
+ </div>
194
+
195
+ <!-- ── Footer ── -->
196
+ <div class="ftr">
197
+ <b>FORWARD IMPACT TEAM</b>
198
+ <span
199
+ >Confidential &mdash; prepared by {{AUTHOR_NAME}}, {{AUTHOR_ROLE}}</span
200
+ >
201
+ </div>
202
+ </body>
203
+ </html>
@@ -0,0 +1,438 @@
1
+ /*
2
+ * candidate-report — A4 single-page candidate assessment report
3
+ *
4
+ * This stylesheet is designed for a 210mm × 297mm page.
5
+ * It is loaded into the HTML template by the candidate-report skill.
6
+ *
7
+ * IMPORTANT: All colours must use print-color-adjust: exact so they survive
8
+ * PDF rendering via Playwright. Avoid box-shadow and fixed positioning.
9
+ */
10
+
11
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap");
12
+
13
+ :root {
14
+ --blue: #0072ce;
15
+ --dark: #003087;
16
+ --accent: #00a3e0;
17
+ --green: #10b981;
18
+ --amber: #f59e0b;
19
+ --red: #ef4444;
20
+ --s50: #f8fafc;
21
+ --s100: #f1f5f9;
22
+ --s200: #e2e8f0;
23
+ --s300: #cbd5e1;
24
+ --s400: #94a3b8;
25
+ --s500: #64748b;
26
+ --s600: #475569;
27
+ --s700: #334155;
28
+ --s800: #1e293b;
29
+ --s900: #0f172a;
30
+ }
31
+
32
+ @page {
33
+ size: A4;
34
+ margin: 0;
35
+ }
36
+
37
+ * {
38
+ margin: 0;
39
+ padding: 0;
40
+ box-sizing: border-box;
41
+ }
42
+
43
+ body {
44
+ font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
45
+ color: var(--s800);
46
+ line-height: 1.45;
47
+ -webkit-font-smoothing: antialiased;
48
+ width: 210mm;
49
+ min-height: 297mm;
50
+ max-height: 297mm;
51
+ overflow: hidden;
52
+ margin: 0 auto;
53
+ background: white;
54
+ }
55
+
56
+ /* ── Header ── */
57
+
58
+ .hdr {
59
+ background: linear-gradient(
60
+ 135deg,
61
+ var(--dark),
62
+ var(--blue) 60%,
63
+ var(--accent)
64
+ );
65
+ padding: 22px 32px 18px;
66
+ color: white;
67
+ display: flex;
68
+ justify-content: space-between;
69
+ align-items: flex-end;
70
+ print-color-adjust: exact;
71
+ -webkit-print-color-adjust: exact;
72
+ }
73
+ .hdr-left h1 {
74
+ font-size: 22px;
75
+ font-weight: 800;
76
+ letter-spacing: -0.3px;
77
+ }
78
+ .hdr-left p {
79
+ font-size: 11px;
80
+ opacity: 0.8;
81
+ margin-top: 2px;
82
+ }
83
+ .hdr-right {
84
+ text-align: right;
85
+ font-size: 10px;
86
+ opacity: 0.75;
87
+ line-height: 1.5;
88
+ }
89
+
90
+ /* ── Verdict Banner ── */
91
+
92
+ .verdict {
93
+ border-left: 4px solid var(--amber);
94
+ padding: 8px 32px;
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 10px;
98
+ font-size: 11px;
99
+ print-color-adjust: exact;
100
+ -webkit-print-color-adjust: exact;
101
+ }
102
+ .verdict strong {
103
+ color: var(--s900);
104
+ font-size: 12px;
105
+ }
106
+ .verdict span {
107
+ color: var(--s600);
108
+ }
109
+
110
+ /* Verdict colour variants — set on the element via class */
111
+ .verdict-caution {
112
+ background: #fef3c7;
113
+ }
114
+ .verdict-pass {
115
+ background: #fee2e2;
116
+ }
117
+ .verdict-proceed {
118
+ background: #d1fae5;
119
+ }
120
+
121
+ /* ── Body ── */
122
+
123
+ .body {
124
+ padding: 16px 32px 14px;
125
+ display: flex;
126
+ flex-direction: column;
127
+ gap: 14px;
128
+ }
129
+
130
+ /* ── Section Titles ── */
131
+
132
+ .stitle {
133
+ font-size: 10px;
134
+ font-weight: 700;
135
+ letter-spacing: 1.5px;
136
+ text-transform: uppercase;
137
+ color: var(--blue);
138
+ margin-bottom: 6px;
139
+ padding-bottom: 4px;
140
+ border-bottom: 1.5px solid var(--s200);
141
+ }
142
+
143
+ /* ── Two-Column Layout ── */
144
+
145
+ .cols {
146
+ display: flex;
147
+ gap: 20px;
148
+ }
149
+ .col {
150
+ flex: 1;
151
+ }
152
+
153
+ /* ── Snapshot (definition list) ── */
154
+
155
+ .snap {
156
+ font-size: 11px;
157
+ line-height: 1.6;
158
+ }
159
+ .snap dt {
160
+ font-weight: 600;
161
+ color: var(--s400);
162
+ font-size: 9px;
163
+ letter-spacing: 0.5px;
164
+ text-transform: uppercase;
165
+ }
166
+ .snap dd {
167
+ margin-bottom: 4px;
168
+ color: var(--s800);
169
+ }
170
+
171
+ /* ── Strengths List ── */
172
+
173
+ .str-list {
174
+ list-style: none;
175
+ font-size: 11px;
176
+ color: var(--s600);
177
+ }
178
+ .str-list li {
179
+ padding: 3px 0;
180
+ padding-left: 14px;
181
+ position: relative;
182
+ }
183
+ .str-list li::before {
184
+ content: "";
185
+ position: absolute;
186
+ left: 0;
187
+ top: 10px;
188
+ width: 6px;
189
+ height: 6px;
190
+ border-radius: 2px;
191
+ background: var(--blue);
192
+ print-color-adjust: exact;
193
+ -webkit-print-color-adjust: exact;
194
+ }
195
+ .str-list li strong {
196
+ color: var(--s800);
197
+ }
198
+
199
+ /* ── Level Gauge ── */
200
+
201
+ .gauge {
202
+ display: flex;
203
+ gap: 0;
204
+ border-radius: 6px;
205
+ overflow: hidden;
206
+ border: 1px solid var(--s200);
207
+ margin-top: 2px;
208
+ }
209
+ .gauge div {
210
+ flex: 1;
211
+ text-align: center;
212
+ padding: 7px 4px;
213
+ font-size: 11px;
214
+ font-weight: 700;
215
+ background: var(--s50);
216
+ border-right: 1px solid var(--s200);
217
+ color: var(--s400);
218
+ print-color-adjust: exact;
219
+ -webkit-print-color-adjust: exact;
220
+ }
221
+ .gauge div:last-child {
222
+ border-right: none;
223
+ }
224
+ .gauge div small {
225
+ display: block;
226
+ font-size: 8px;
227
+ font-weight: 500;
228
+ margin-top: 1px;
229
+ }
230
+ .gauge .cand {
231
+ background: #fef3c7;
232
+ color: #92400e;
233
+ box-shadow: inset 0 0 0 2px var(--amber);
234
+ }
235
+ .gauge .tgt {
236
+ background: #dbeafe;
237
+ color: var(--dark);
238
+ box-shadow: inset 0 0 0 2px var(--blue);
239
+ }
240
+
241
+ /* ── Benchmark Grid ── */
242
+
243
+ .bm {
244
+ display: grid;
245
+ grid-template-columns: 1fr 1fr;
246
+ gap: 6px 16px;
247
+ font-size: 10.5px;
248
+ }
249
+ .bm-area h4 {
250
+ font-size: 10px;
251
+ font-weight: 700;
252
+ color: var(--s700);
253
+ margin-bottom: 3px;
254
+ }
255
+ .bm-row {
256
+ display: flex;
257
+ justify-content: space-between;
258
+ align-items: center;
259
+ padding: 2px 0;
260
+ border-bottom: 1px solid var(--s100);
261
+ }
262
+ .bm-row:last-child {
263
+ border-bottom: none;
264
+ }
265
+ .bm-skill {
266
+ color: var(--s700);
267
+ }
268
+
269
+ /* Status pills */
270
+ .p {
271
+ display: inline-block;
272
+ padding: 1px 7px;
273
+ border-radius: 4px;
274
+ font-size: 9px;
275
+ font-weight: 600;
276
+ white-space: nowrap;
277
+ print-color-adjust: exact;
278
+ -webkit-print-color-adjust: exact;
279
+ }
280
+ .p-g {
281
+ background: #fee2e2;
282
+ color: #991b1b;
283
+ } /* Gap */
284
+ .p-a {
285
+ background: #fef3c7;
286
+ color: #92400e;
287
+ } /* Partial */
288
+ .p-p {
289
+ background: #d1fae5;
290
+ color: #065f46;
291
+ } /* Positive */
292
+ .p-u {
293
+ background: var(--s100);
294
+ color: var(--s500);
295
+ } /* Unknown */
296
+
297
+ /* ── Behaviour Bars ── */
298
+
299
+ .beh {
300
+ display: flex;
301
+ gap: 8px;
302
+ flex-wrap: wrap;
303
+ }
304
+ .beh-item {
305
+ flex: 1;
306
+ min-width: 90px;
307
+ }
308
+ .beh-name {
309
+ font-size: 9px;
310
+ font-weight: 600;
311
+ color: var(--s700);
312
+ margin-bottom: 2px;
313
+ }
314
+ .beh-bar {
315
+ height: 4px;
316
+ border-radius: 2px;
317
+ background: var(--s100);
318
+ overflow: hidden;
319
+ print-color-adjust: exact;
320
+ -webkit-print-color-adjust: exact;
321
+ }
322
+ .beh-bar div {
323
+ height: 100%;
324
+ border-radius: 2px;
325
+ print-color-adjust: exact;
326
+ -webkit-print-color-adjust: exact;
327
+ }
328
+ .beh-tag {
329
+ font-size: 8px;
330
+ color: var(--s400);
331
+ margin-top: 1px;
332
+ }
333
+
334
+ /* ── Coverage Counters ── */
335
+
336
+ .counters {
337
+ display: flex;
338
+ gap: 8px;
339
+ margin-top: 4px;
340
+ }
341
+ .ctr {
342
+ flex: 1;
343
+ text-align: center;
344
+ padding: 8px 4px;
345
+ border-radius: 6px;
346
+ border: 1px solid var(--s200);
347
+ print-color-adjust: exact;
348
+ -webkit-print-color-adjust: exact;
349
+ }
350
+ .ctr .n {
351
+ font-size: 18px;
352
+ font-weight: 800;
353
+ }
354
+ .ctr .l {
355
+ font-size: 8px;
356
+ font-weight: 600;
357
+ text-transform: uppercase;
358
+ letter-spacing: 0.5px;
359
+ }
360
+
361
+ /* ── Recommendation Box ── */
362
+
363
+ .reco {
364
+ background: var(--s50);
365
+ border: 1.5px solid var(--s200);
366
+ border-radius: 8px;
367
+ padding: 10px 14px;
368
+ }
369
+ .reco ol {
370
+ list-style: none;
371
+ counter-reset: s;
372
+ font-size: 11px;
373
+ color: var(--s600);
374
+ }
375
+ .reco li {
376
+ counter-increment: s;
377
+ display: flex;
378
+ gap: 8px;
379
+ margin-bottom: 4px;
380
+ }
381
+ .reco li:last-child {
382
+ margin-bottom: 0;
383
+ }
384
+ .reco li::before {
385
+ content: counter(s);
386
+ width: 18px;
387
+ height: 18px;
388
+ border-radius: 5px;
389
+ background: var(--blue);
390
+ color: white;
391
+ font-size: 10px;
392
+ font-weight: 700;
393
+ display: flex;
394
+ align-items: center;
395
+ justify-content: center;
396
+ flex-shrink: 0;
397
+ margin-top: 1px;
398
+ print-color-adjust: exact;
399
+ -webkit-print-color-adjust: exact;
400
+ }
401
+ .reco li strong {
402
+ color: var(--s800);
403
+ }
404
+
405
+ /* ── Footer ── */
406
+
407
+ .ftr {
408
+ padding: 8px 32px;
409
+ border-top: 1px solid var(--s200);
410
+ display: flex;
411
+ justify-content: space-between;
412
+ font-size: 9px;
413
+ color: var(--s400);
414
+ }
415
+ .ftr b {
416
+ color: var(--blue);
417
+ letter-spacing: 1px;
418
+ }
419
+
420
+ /* ── Print Overrides ── */
421
+
422
+ @media print {
423
+ body {
424
+ width: 210mm;
425
+ height: 297mm;
426
+ }
427
+ .hdr,
428
+ .verdict,
429
+ .gauge div,
430
+ .p,
431
+ .str-list li::before,
432
+ .beh-bar div,
433
+ .ctr,
434
+ .reco li::before {
435
+ print-color-adjust: exact !important;
436
+ -webkit-print-color-adjust: exact !important;
437
+ }
438
+ }
@@ -0,0 +1,76 @@
1
+ # Benchmarking Rubric
2
+
3
+ Reference data for `candidate-report` Step 3 (benchmark) and Step 4 (verdict).
4
+
5
+ ## Skill ratings
6
+
7
+ Map each agent-aligned engineering standard skill against candidate evidence (CV
8
+ or `screening.md`).
9
+
10
+ | Rating | Criteria | Pill class |
11
+ | ----------- | -------------------------------------------------- | ---------- |
12
+ | **Met** | Evidence meets or exceeds the expected proficiency | `p-p` |
13
+ | **Partial** | Some evidence but below expected level | `p-a` |
14
+ | **Gap** | No evidence, or clearly below expected | `p-g` |
15
+ | **Unknown** | Cannot assess from available evidence | `p-u` |
16
+
17
+ Apply the **two-level scepticism rule** from `req-screen`: default two levels
18
+ below CV claims unless concrete, quantified evidence is provided.
19
+
20
+ ## Behaviour bar widths
21
+
22
+ Map each agent-aligned behaviour to a 0–100 % width and a CSS variable based on
23
+ evidence strength.
24
+
25
+ | Range | Signal | Colour |
26
+ | -------- | --------------- | -------------- |
27
+ | 60–100 % | Positive signal | `var(--green)` |
28
+ | 30–59 % | Partial signal | `var(--amber)` |
29
+ | 10–29 % | Weak / unknown | `var(--s300)` |
30
+ | 0–9 % | Gap | `var(--red)` |
31
+
32
+ ## Level gauge
33
+
34
+ Estimate the candidate's realistic level. Choose a 5-level window centred on the
35
+ candidate's estimate and the target level.
36
+
37
+ ## Verdict
38
+
39
+ Pick one verdict class for the report header.
40
+
41
+ | Verdict | Class | When to use |
42
+ | -------------------- | ----------------- | ------------------------------------------------------------------- |
43
+ | Proceed | `verdict-proceed` | Candidate benchmarks at or above target level |
44
+ | Proceed with Caution | `verdict-caution` | Mixed signals; viable for scoped role or needs interview to resolve |
45
+ | Pass | `verdict-pass` | Clear misalignment with role requirements |
46
+
47
+ Write a one-line headline and a brief detail sentence.
48
+
49
+ ## Template sections to populate
50
+
51
+ Drives the placeholder substitution in Step 5.
52
+
53
+ | Section | Source |
54
+ | ----------------- | ---------------------------------------------------- |
55
+ | Header | Candidate name, title, org, location from `brief.md` |
56
+ | Verdict | This file's verdict table |
57
+ | Snapshot | 5–6 key facts (experience, education, source, stack) |
58
+ | Strengths | 3–5 bullet points — what the candidate brings |
59
+ | Level gauge | Estimated vs target level |
60
+ | Benchmark grid | Top skills per capability area with pills |
61
+ | Behaviours | Bar chart items with widths and colours |
62
+ | Coverage counters | Gap / Partial / Unknown / Met counts |
63
+ | Recommendation | 2–4 actionable next steps |
64
+ | Footer | Author name and role from `USER.md` |
65
+
66
+ ## A4 single-page budget
67
+
68
+ The report **must** fit on a single A4 page (210mm × 297mm):
69
+
70
+ - Snapshot: max 6 `<dt>`/`<dd>` pairs.
71
+ - Strengths: max 5 `<li>`, one sentence each.
72
+ - Benchmark grid: 4–6 rows per capability area; prioritise notable
73
+ gaps/strengths, omit "Unknown" rows when tight.
74
+ - Combine small capability areas (e.g. Docs + ML) into one block.
75
+ - Recommendation: max 4 `<li>`.
76
+ - Test with browser print preview (Ctrl+P); cut content if it overflows.