pi-career 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/NOTICE +11 -20
- package/README.md +397 -80
- package/SECURITY.md +26 -18
- package/dist/index.js +2787 -493
- package/dist/pdf-worker.js +115 -0
- package/docs/application-workspaces.md +144 -0
- package/docs/career-run-roadmap.md +256 -0
- package/docs/design.md +43 -42
- package/docs/native-dependency-inventory.md +6 -6
- package/docs/product-flow.md +33 -17
- package/docs/releasing.md +114 -67
- package/{runtime/LICENSE-MIT → docs/unpdf-LICENSE-MIT.txt} +1 -1
- package/package.json +10 -9
- package/skills/career-core/SKILL.md +91 -43
- package/skills/career-core/references/cli-contract.md +47 -25
- package/runtime/LICENSE-APACHE +0 -201
- package/runtime/THIRD_PARTY_NOTICES.md +0 -22
- package/runtime/darwin-arm64/career +0 -0
- package/runtime/darwin-arm64/provenance.json +0 -101
- package/runtime/linux-x64-gnu/career +0 -0
- package/runtime/linux-x64-gnu/provenance.json +0 -101
- package/runtime/manifest.json +0 -109
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Application workspace design
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
A single active vacancy on a Pi session branch is not enough to organize a real job search. Users need an explicit boundary for each company/role combination so resume changes, cover letters, notes, and status do not leak into another application. Application artifacts must also stay out of original-resume indexing.
|
|
6
|
+
|
|
7
|
+
This document defines the target workspace contract. The current package does not create these private files yet; that requires a separately reviewed, explicit persistence workflow.
|
|
8
|
+
|
|
9
|
+
The current `/career-setup` preferred resume-variation directory is narrower and suggestion-only. It gives the selected Pi agent a primary destination to recommend after a separate user request, defaults to `variants/` under the selected original's configured root, and creates nothing. It is not the future application workspace root and does not relax the persistence requirements below.
|
|
10
|
+
|
|
11
|
+
## Directory model
|
|
12
|
+
|
|
13
|
+
Resume originals and application work must be separate roots:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
career-home/
|
|
17
|
+
originals/
|
|
18
|
+
master-resume.pdf
|
|
19
|
+
engineering-resume.md
|
|
20
|
+
applications/
|
|
21
|
+
synthetic-company-senior-engineer-a1b2c3d4/
|
|
22
|
+
application.json
|
|
23
|
+
vacancy.md
|
|
24
|
+
changes.md
|
|
25
|
+
resume.md
|
|
26
|
+
resume.pi-career.json
|
|
27
|
+
cover-letter.md
|
|
28
|
+
notes.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Keep one flat directory per application. Do not add company-level or artifact-type subdirectories. Optional preparation files such as `interview.md` can sit beside the standard files.
|
|
32
|
+
|
|
33
|
+
The application workspace must not be nested inside a directory scanned as an original-resume root unless the scanner has an exact configured exclusion for it. Broad name-based exclusions such as ignoring every `applications/` directory are not acceptable.
|
|
34
|
+
|
|
35
|
+
## Identity and collisions
|
|
36
|
+
|
|
37
|
+
One application represents one company/role attempt and receives an immutable random application ID. Its directory name is a display convenience, not authority:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
<bounded-company-slug>-<bounded-role-slug>-<application-id-prefix>/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Two roles at one company and repeated applications to one role therefore remain distinct. Renaming a display label does not change application identity.
|
|
44
|
+
|
|
45
|
+
A future exact manifest schema should contain only bounded metadata and digests, for example:
|
|
46
|
+
|
|
47
|
+
- schema version
|
|
48
|
+
- application ID
|
|
49
|
+
- bounded company label
|
|
50
|
+
- bounded role label
|
|
51
|
+
- status
|
|
52
|
+
- created/updated timestamps
|
|
53
|
+
- selected original resume ID and text digest
|
|
54
|
+
- vacancy text digest
|
|
55
|
+
- assisted artifact relative paths and digests
|
|
56
|
+
|
|
57
|
+
It must not contain absolute paths, provider credentials, provider responses, or unreviewed raw model output.
|
|
58
|
+
|
|
59
|
+
## Original and styling boundary
|
|
60
|
+
|
|
61
|
+
Original resumes are immutable:
|
|
62
|
+
|
|
63
|
+
- Never overwrite, rename, move, or reformat an original automatically.
|
|
64
|
+
- A PDF workbench has extracted text only. It cannot inspect or preserve typography, columns, spacing, graphics, or other visual layout.
|
|
65
|
+
- Current PDF workbench output is limited to reviewed change guidance and bounded before/after snippets for manual application; pi-career does not save a PDF change plan.
|
|
66
|
+
- Current Markdown/text materialization can return assisted text in process memory after user selection. A future save phase may write that text to a new file only under the approval and sidecar rules below.
|
|
67
|
+
- DOCX/Pages/other styled-source mutation remains unsupported until format-specific fidelity and safety are designed and tested.
|
|
68
|
+
- Every generated resume file is assisted/non-authoritative, has a valid sidecar, and is excluded from authoritative readiness analysis and job matching.
|
|
69
|
+
|
|
70
|
+
Copying the original into every application is not the default. The application manifest references the configured original by package ID and digest. A user may separately choose to place their own editable source in the application folder.
|
|
71
|
+
|
|
72
|
+
## Artifact roles
|
|
73
|
+
|
|
74
|
+
| Artifact | Purpose | Authority |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `application.json` | Bounded application identity/status/digests | Local workflow state only |
|
|
77
|
+
| `vacancy.md` | User-approved local copy of the vacancy | Original user input, not normalized rewrite |
|
|
78
|
+
| `changes.md` | Reviewed targeted changes and verification checklist | Assisted/non-authoritative |
|
|
79
|
+
| `resume.md` plus sidecar | New user-selected assisted variant | Assisted/non-authoritative; never reranked |
|
|
80
|
+
| `cover-letter.md` | Application-specific draft | Assisted/non-authoritative |
|
|
81
|
+
| `notes.md` | User-owned preparation notes | Not Career Core input unless explicitly selected later |
|
|
82
|
+
|
|
83
|
+
No raw provider response should be written automatically. A bounded artifact is saved only after the user reviews and approves its exact destination and content.
|
|
84
|
+
|
|
85
|
+
## Session and privacy model
|
|
86
|
+
|
|
87
|
+
Use one Pi session per application. Start `/new` before `/career-application` for another company/role so earlier private prompts and provider responses do not remain in the next application conversation.
|
|
88
|
+
|
|
89
|
+
The current application workflow binds only:
|
|
90
|
+
|
|
91
|
+
- application ID, company/role labels, and status;
|
|
92
|
+
- the current vacancy;
|
|
93
|
+
- bounded deterministic analysis/match cards.
|
|
94
|
+
|
|
95
|
+
Selected-original handles, complete Core results, exact review inputs, and materialized text remain process-memory-only. A submitted workbench message may persist as an ordinary Pi conversation entry, but pi-career does not store it as application workspace state. Assisted artifact references are not implemented yet.
|
|
96
|
+
|
|
97
|
+
A persisted Pi session can still contain private prompts and tool arguments. Application-file approval is separate from Pi session persistence and separate from provider disclosure. The workflow must ask before the first private workspace write and show the exact workspace path and files to be created.
|
|
98
|
+
|
|
99
|
+
A transient `pi --no-session` run prevents Pi session JSONL persistence but does not imply temporary application files or secure erasure. Workspace creation must remain an explicit independent action.
|
|
100
|
+
|
|
101
|
+
## Target workflow for future workspace persistence
|
|
102
|
+
|
|
103
|
+
This sequence extends the current in-session flow; steps involving an application workspace root or file writes are not implemented.
|
|
104
|
+
|
|
105
|
+
1. A future `/career-setup` phase configures original-resume roots and a separate application workspace root.
|
|
106
|
+
2. In a fresh Pi session, `/career-application` creates one consented company/role context; it does not write files or switch that session to another company.
|
|
107
|
+
3. `/career-vacancy` binds the vacancy to that application.
|
|
108
|
+
4. `/career-match` ranks eligible originals and records the selected original reference.
|
|
109
|
+
5. `/career-workbench` prepares a visible guided editor prompt that reruns complete deterministic baselines after submission; its rewrite interview can ask one bounded batch of factual questions and wait for a later answer.
|
|
110
|
+
6. External suggestions, replacements, or vacancy-specific variant changes use exact verbatim source targets and are reviewed once by exact Career Core schemas; discarded proposals are reported rather than automatically repaired or retried.
|
|
111
|
+
7. For a non-PDF variant, the first assisted turn stops so the user can explicitly select canonical retained change IDs; only a later turn materializes those exact selections.
|
|
112
|
+
8. A future save action separately requests local-file approval, previews exact new files, and writes only inside the selected application directory.
|
|
113
|
+
9. Originals remain unchanged, and assisted variants remain excluded from authoritative reranking.
|
|
114
|
+
|
|
115
|
+
## Implementation phases
|
|
116
|
+
|
|
117
|
+
### Phase A: implemented
|
|
118
|
+
|
|
119
|
+
- searchable PDF indexing and actionable notices
|
|
120
|
+
- visible, bounded workbench editor handoff
|
|
121
|
+
- immutable-original and format-fidelity instructions
|
|
122
|
+
- branch-aware application metadata in consented custom session entries
|
|
123
|
+
- company/role/status selection and vacancy/result binding to application ID
|
|
124
|
+
- flat application workspace contract with no private application-file writes
|
|
125
|
+
|
|
126
|
+
### Phase B: workspace configuration
|
|
127
|
+
|
|
128
|
+
- separate configured original-resume and application workspace roots
|
|
129
|
+
- exact application-root exclusion from resume scanning
|
|
130
|
+
- preview-only directory/file plan with no writes
|
|
131
|
+
|
|
132
|
+
### Phase C: explicit workspace persistence
|
|
133
|
+
|
|
134
|
+
Requires separate review of:
|
|
135
|
+
|
|
136
|
+
- config schema migration for an application workspace root
|
|
137
|
+
- canonical containment and symlink/race protections
|
|
138
|
+
- exact manifest and sidecar schemas
|
|
139
|
+
- atomic bounded writes and file modes
|
|
140
|
+
- collision behavior and idempotency
|
|
141
|
+
- file preview/approval UI
|
|
142
|
+
- application-root scan exclusion
|
|
143
|
+
- retention, removal, and uninstall semantics
|
|
144
|
+
- package tests using synthetic artifacts only
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Managed Career Core and `career_run` roadmap
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Career Core Phase 8 was merged as `f6d1783` through PR #21. The first compact `career_run` implementation, ephemeral handles, complete bounded in-memory results, detail hydration, raw-tool activation control, and synthetic token benchmark are implemented here. Runtime distribution now belongs to reviewed exact `@revazi/career@0.1.1`; pi-career packages no native artifacts and resolves compatible external routes before managed execution. Package-owned save/export, richer interactive change selection/navigation, and broader PDF extraction compatibility remain later reviewed work.
|
|
6
|
+
|
|
7
|
+
Completed sequence:
|
|
8
|
+
|
|
9
|
+
1. Career Core Phase 8 managed-adapter support.
|
|
10
|
+
2. Native Phase 8 artifact preparation and compatibility review.
|
|
11
|
+
3. Artifact import with provenance/catalog/bundle/output-bound verification.
|
|
12
|
+
4. Primary `career_run` implementation with raw tools inactive by default.
|
|
13
|
+
5. Reproducible synthetic context benchmark and budget gates.
|
|
14
|
+
6. External local-first resolver with exact package acquisition, pre-private-input compatibility validation, and removal of bundled native artifacts.
|
|
15
|
+
|
|
16
|
+
This document records findings and phase boundaries; it does not independently authorize persistence, publication, release, or later deferred work.
|
|
17
|
+
|
|
18
|
+
## Findings motivating the migration
|
|
19
|
+
|
|
20
|
+
The integration gap is adapter design rather than implementation language. Pi Fallow also invokes its Rust core through a CLI subprocess, but provides a substantially more agent-oriented boundary:
|
|
21
|
+
|
|
22
|
+
- one compact `fallow_run` tool
|
|
23
|
+
- implicit project context
|
|
24
|
+
- simple command routing
|
|
25
|
+
- compact summaries with detail on demand
|
|
26
|
+
- progress and custom rendering
|
|
27
|
+
- interactive finding navigation and selection
|
|
28
|
+
- cached runtime resolution and normalized output
|
|
29
|
+
- token and performance benchmarks
|
|
30
|
+
|
|
31
|
+
Local `o200k_base` measurements taken during the design review:
|
|
32
|
+
|
|
33
|
+
| Surface | Tokens |
|
|
34
|
+
|---|---:|
|
|
35
|
+
| Current `fallow_run` contract | 338 |
|
|
36
|
+
| Current three pi-career native tool contracts | 1,041 |
|
|
37
|
+
| Empty synthetic career workbench prompt before real source content | 706 |
|
|
38
|
+
| Small synthetic Career Core analysis-replacement review result | 4,744 |
|
|
39
|
+
|
|
40
|
+
The current raw-tool workflow can require the model to discover schemas, manually construct nested JSON strings, repeat complete original/proposal payloads, parse exhaustive Core results, and reconstruct a materialization envelope containing the full review input. This increases context use and created avoidable malformed-envelope and exact-evidence-target friction in a representative end-to-end resume workflow.
|
|
41
|
+
|
|
42
|
+
## Delivered initial agent experience
|
|
43
|
+
|
|
44
|
+
The primary interface is now one compact high-level Pi tool:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
career_run {command: context}
|
|
48
|
+
career_run {command: analyze, handle: resume:...}
|
|
49
|
+
career_run {command: match, handle: resume:...}
|
|
50
|
+
career_run {command: variant-review, handle: resume:..., payload: {changes: [...]}}
|
|
51
|
+
career_run {command: materialize, handle: review:..., payload: {selected_change_ids: [...]}}
|
|
52
|
+
career_run {command: detail, handle: result:..., payload: {section: evidence}}
|
|
53
|
+
# package-owned save remains deferred
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This is the implemented compact v1 command shape; package-owned save remains deferred. Private document text continues to travel only through bounded stdin at the Career Core process boundary, never through CLI arguments.
|
|
57
|
+
|
|
58
|
+
Career Core remains authoritative for operations, schemas, algorithms, typed errors, evidence, warnings, uncertainty, ordering, deterministic baselines, and assisted/non-authoritative semantics. Pi-career owns handles, orchestration, projection, interaction, and explicitly approved persistence.
|
|
59
|
+
|
|
60
|
+
## Career Core Phase 8: delivered managed-adapter support
|
|
61
|
+
|
|
62
|
+
The explicitly authorized and reviewed Career Core Phase 8 added only the machine contracts needed by a managed adapter.
|
|
63
|
+
|
|
64
|
+
### Operation catalog
|
|
65
|
+
|
|
66
|
+
Phase 8 added the deterministic machine command:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
career operations --format json-compact
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
It should return a versioned `career.operation_catalog.v1` document mapping every callable available operation to:
|
|
73
|
+
|
|
74
|
+
- stable operation ID
|
|
75
|
+
- availability status
|
|
76
|
+
- CLI path segments
|
|
77
|
+
- input transport
|
|
78
|
+
- input schema ID, when applicable
|
|
79
|
+
- output schema ID
|
|
80
|
+
- maximum input bytes
|
|
81
|
+
- maximum successful machine-output bytes
|
|
82
|
+
|
|
83
|
+
Do not add fields to `career.capabilities.v1`: its current schema rejects additional properties. The operation catalog should be a separate compatible contract with stable ordering and complete capability/operation mapping tests.
|
|
84
|
+
|
|
85
|
+
### Self-contained schema bundles
|
|
86
|
+
|
|
87
|
+
Phase 8 added the deterministic offline command:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
career schema bundle --id career.resume_variant_review_input.v1
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Bundled output recursively resolves only embedded local references, requires no source checkout or network, remains valid Draft 2020-12 JSON Schema, and is deterministic and bounded. Existing unbundled schema-export bytes remain unchanged.
|
|
94
|
+
|
|
95
|
+
This lets pi-career validate exact Core envelopes without copying Core schemas into TypeScript or exposing schema discovery to the model during normal workflows.
|
|
96
|
+
|
|
97
|
+
### Machine-output bounds
|
|
98
|
+
|
|
99
|
+
Phase 8 documents and enforces one 32-MiB maximum successful JSON output size and reports it for every operation in the catalog. The bound covers every valid bounded Core result.
|
|
100
|
+
|
|
101
|
+
Pi-career captures complete authoritative JSON within that limit, keeps it only in ephemeral memory, and exposes compact model-facing projections with explicit detail hydration. An oversized Core result is never silently truncated.
|
|
102
|
+
|
|
103
|
+
### Artifact compatibility metadata
|
|
104
|
+
|
|
105
|
+
The imported maintainer-only artifact metadata and verification now include:
|
|
106
|
+
|
|
107
|
+
- operation-catalog schema version and digest
|
|
108
|
+
- complete available capability-to-operation mapping
|
|
109
|
+
- representative bundled-schema IDs and digests
|
|
110
|
+
- declared machine-output bounds
|
|
111
|
+
- representative deterministic operation outputs
|
|
112
|
+
|
|
113
|
+
The existing native target, source SHA, dirty-state, executable hash/size/mode, license, and synthetic parity checks remain mandatory.
|
|
114
|
+
|
|
115
|
+
### Phase 8 exclusions
|
|
116
|
+
|
|
117
|
+
Career Core must not add:
|
|
118
|
+
|
|
119
|
+
- the Pi `career_run` tool
|
|
120
|
+
- resume, vacancy, review, result, or variant handles
|
|
121
|
+
- session state or result registries
|
|
122
|
+
- compact model-facing presentation policy
|
|
123
|
+
- UI, selection dialogs, PDF extraction, PDF rendering, or file export
|
|
124
|
+
- source/result persistence
|
|
125
|
+
- model/provider calls, prompts, credentials, networking, telemetry, or retries
|
|
126
|
+
- generated-prose repair, automatic acceptance, or factuality upgrades
|
|
127
|
+
- acceptance of assisted variants by authoritative analysis or matching
|
|
128
|
+
- N-API, MCP, or another protocol solely for this migration
|
|
129
|
+
- npm/PATH/npx runtime fallback or publication
|
|
130
|
+
|
|
131
|
+
Existing Core algorithms and successful v1 operation outputs remain byte-equivalent.
|
|
132
|
+
|
|
133
|
+
### Phase 8 documentation
|
|
134
|
+
|
|
135
|
+
The Career Core change updated:
|
|
136
|
+
|
|
137
|
+
- `.agents/current-phase.md`
|
|
138
|
+
- `.agents/phases.md`
|
|
139
|
+
- `.agents/agent-integration.md`
|
|
140
|
+
- `docs/agent-usage.md`
|
|
141
|
+
- `docs/cli.md`
|
|
142
|
+
- `docs/distribution.md`
|
|
143
|
+
- `README.md`
|
|
144
|
+
|
|
145
|
+
Raw generic agents remain discovery-first. A reviewed managed adapter may perform and cache discovery internally so the model does not need model-visible capability or schema calls.
|
|
146
|
+
|
|
147
|
+
### Phase 8 accepted criteria
|
|
148
|
+
|
|
149
|
+
1. Every existing successful operation output remains byte-equivalent.
|
|
150
|
+
2. Every available capability maps to exactly one callable operation descriptor.
|
|
151
|
+
3. Every input-taking operation identifies its exact input/output schemas and byte bounds.
|
|
152
|
+
4. Every bundled schema resolves offline with no unresolved or remote reference.
|
|
153
|
+
5. Catalogs and schema bundles are deterministic and independently validated.
|
|
154
|
+
6. Machine-output bounds are documented, enforced, and covered at boundary conditions.
|
|
155
|
+
7. Installed-CLI verification passes outside the source checkout.
|
|
156
|
+
8. Native artifact metadata proves the new adapter contracts and representative results.
|
|
157
|
+
9. Swift behavior remains unchanged unless separately justified and authorized.
|
|
158
|
+
10. No provider, network, persistence, UI, filesystem-domain, or model behavior enters Core.
|
|
159
|
+
|
|
160
|
+
## Pi-career managed adapter phase
|
|
161
|
+
|
|
162
|
+
Pi-career now uses one primary compact `career_run` tool. The existing `career_core_discover`, `career_core_resume`, and `career_core_job` tools remain registered as inactive advanced/debugging compatibility tools rather than occupying normal model context; `/career-tools raw` enables them explicitly.
|
|
163
|
+
|
|
164
|
+
### Ephemeral handles
|
|
165
|
+
|
|
166
|
+
The extension maintains bounded in-memory references such as:
|
|
167
|
+
|
|
168
|
+
```text
|
|
169
|
+
resume:<stable-prefix>
|
|
170
|
+
vacancy:current
|
|
171
|
+
review:abc123
|
|
172
|
+
result:def456
|
|
173
|
+
variant:ghi789
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The model sends handles. Pi-career resolves selected local originals and current vacancy state, constructs exact Core envelopes, and reuses the exact cached review input for materialization. Complete private payloads and Core results are not persisted by default; deterministic operations are rerun after restart when necessary.
|
|
177
|
+
|
|
178
|
+
Handles must not weaken the existing persistence decision or provider-consent boundary. The model still needs source content when generating changes, but unchanged source should not be duplicated through every later Core tool argument and result.
|
|
179
|
+
|
|
180
|
+
### Internal discovery and routing
|
|
181
|
+
|
|
182
|
+
Pi-career discovers the operation catalog and required schema bundles for the selected compatible Core route, validates compatibility before private input, and caches only non-sensitive metadata. Normal `career_run` calls never require the model to export schemas or manually encode nested `input_json` strings.
|
|
183
|
+
|
|
184
|
+
### Compact results and hydration
|
|
185
|
+
|
|
186
|
+
Common results include only the decision surface needed for the next action while preserving every mandatory warning and relevant evidence, uncertainty, authority, discard, and limitation field. A stable ephemeral result handle supports bounded detail requests for checks, evidence, reviewed changes, document text, or complete raw JSON.
|
|
187
|
+
|
|
188
|
+
The complete Core result must be captured before projection, remain unchanged, and be recoverable in the current process. It must never be partially consumed after truncation. Resume/job payloads and full results must not be written to temp files without a separately approved design.
|
|
189
|
+
|
|
190
|
+
### Deferred richer review rendering and selection
|
|
191
|
+
|
|
192
|
+
A later reviewed phase may add bounded custom rendering for:
|
|
193
|
+
|
|
194
|
+
- before/proposed-after changes
|
|
195
|
+
- evidence and source targets
|
|
196
|
+
- confirmed/provisional status
|
|
197
|
+
- warnings and factuality limitations
|
|
198
|
+
- discard codes
|
|
199
|
+
|
|
200
|
+
The initial managed adapter already requires explicit canonical change IDs and reuses the exact complete reviewed proposal for materialization; the model must not select automatically. A later bounded multi-select interaction may make that user decision easier without changing the authority boundary.
|
|
201
|
+
|
|
202
|
+
### Approved save workflow
|
|
203
|
+
|
|
204
|
+
A later explicitly authorized save action should require:
|
|
205
|
+
|
|
206
|
+
1. exact destination and file preview
|
|
207
|
+
2. explicit user confirmation
|
|
208
|
+
3. atomic `0600` writes in a `0700` managed directory
|
|
209
|
+
4. collision-safe naming
|
|
210
|
+
5. assisted/non-authoritative sidecar metadata and content hashes
|
|
211
|
+
6. immutable originals and overwrite rejection
|
|
212
|
+
7. immediate library rescan with variants excluded from authoritative analysis/matching
|
|
213
|
+
|
|
214
|
+
Destination configuration remains suggestion-only until this phase is designed, threat-reviewed, implemented, and tested.
|
|
215
|
+
|
|
216
|
+
### Document ingestion
|
|
217
|
+
|
|
218
|
+
To broaden confidence beyond the current searchable-PDF fixtures, extend synthetic compatibility tests to cover Chromium-generated PDFs, common embedded fonts, multi-column documents, and tagged/untagged searchable PDFs. Continue to reject encrypted, image-only, malformed, oversized, or timed-out PDFs without OCR unless OCR receives separate authorization.
|
|
219
|
+
|
|
220
|
+
### UX and context benchmarks
|
|
221
|
+
|
|
222
|
+
The initial frozen synthetic benchmark covers the active/raw tool contracts, representative analyze and variant-review results, and the existing workbench prompt. Later benchmark expansion should cover:
|
|
223
|
+
|
|
224
|
+
- match, suggestion/replacement-review, materialization, and hydration result tokens
|
|
225
|
+
- model turns and tool calls
|
|
226
|
+
- mandatory warning/evidence/uncertainty retention
|
|
227
|
+
- repeated private-source bytes
|
|
228
|
+
- malformed-envelope prevention
|
|
229
|
+
- TUI and RPC behavior
|
|
230
|
+
- cold/warm runtime performance and memory
|
|
231
|
+
|
|
232
|
+
Initial targets:
|
|
233
|
+
|
|
234
|
+
- primary active tool contract at or below 400 `o200k_base` tokens
|
|
235
|
+
- no model-visible schema-export step in the managed flow
|
|
236
|
+
- no nested `input_json`
|
|
237
|
+
- original source included at most once per model workflow unless explicitly requested again
|
|
238
|
+
- common result at or below roughly 1,500 tokens
|
|
239
|
+
- complete authoritative detail recoverable on demand
|
|
240
|
+
- review → explicit selection → materialization without rebuilding the Core envelope
|
|
241
|
+
|
|
242
|
+
## Runtime boundaries retained after externalization
|
|
243
|
+
|
|
244
|
+
Pi-career retains:
|
|
245
|
+
|
|
246
|
+
- no packaged native runtime artifacts or runtime dependencies
|
|
247
|
+
- fixed resolution through explicit `CAREER_CLI_PATH`, PATH `career`, package-local exact `@revazi/career`, then acquisition of exact `@revazi/career@0.1.1`
|
|
248
|
+
- no Cargo, sibling checkout, source build, arbitrary executable download, unpinned package, or lifecycle fallback
|
|
249
|
+
- `PI_OFFLINE=1` disables acquisition; the only implicit network-capable behavior is bounded exact-package acquisition after local routes fail and before private stdin opens
|
|
250
|
+
- exact managed compatibility for caller-controlled routes and native integrity delegated to the reviewed package launcher
|
|
251
|
+
- no automatic repair or retry of rejected external proposals
|
|
252
|
+
- no uncertainty, evidence, recommendation, or factuality upgrades
|
|
253
|
+
- no unapproved private full-result temp files
|
|
254
|
+
- no automatic source mutation or original overwrite
|
|
255
|
+
|
|
256
|
+
The desired parity with Pi Fallow is the compact tool, orchestration, rendering, navigation, compatibility, cancellation, and benchmark discipline—not a relaxation of Career Core's deterministic or pi-career's privacy and supply-chain boundaries.
|
package/docs/design.md
CHANGED
|
@@ -1,78 +1,79 @@
|
|
|
1
|
-
#
|
|
1
|
+
# External-runtime adapter design and threat model
|
|
2
2
|
|
|
3
3
|
## Scope and authority
|
|
4
4
|
|
|
5
|
-
`pi-career` is a
|
|
5
|
+
`pi-career` is a public Pi adapter package for reviewed Career Core targets. It owns the Pi extension, external runtime resolver, Pi-facing Agent Skill, generated TypeScript bundles, package tests, and integration guidance. It does **not** own or package native Career Core binaries. Career Core remains authoritative for operations, schemas, algorithms, errors, evidence, warnings, uncertainty, ordering, and assisted/non-authoritative semantics; this repository does not copy those contracts or algorithms into TypeScript.
|
|
6
6
|
|
|
7
|
-
The
|
|
7
|
+
The primary managed Pi surface is `career_run`. It uses ephemeral resume/result/review/variant handles, internal Career Core operation/schema discovery, compact projections, and bounded detail hydration. The exact raw compatibility tools remain registered but are normally inactive:
|
|
8
8
|
|
|
9
9
|
- `career_core_discover`
|
|
10
10
|
- `career_core_resume`
|
|
11
11
|
- `career_core_job`
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
`/career-tools managed|raw|status` controls whether the raw tools occupy active model context; it never changes the process, compatibility, privacy, or runtime-resolution boundary.
|
|
14
14
|
|
|
15
|
-
The
|
|
15
|
+
The TypeScript source is authoritative. Checked-in deterministic `dist/index.js` and `dist/pdf-worker.js` bundles support clean local, pinned-Git, and npm Pi loading without packaged runtime dependencies. The isolated PDF worker bundles the reviewed text extractor; Pi-provided imports remain external peers. Package metadata permits only separately reviewed public publication of the unscoped `pi-career` package to the canonical npm registry.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The workflow layer registers `/career-setup`, `/career-library`, `/career-application`, `/career-vacancy`, `/career-match`, `/career-analyze`, and `/career-workbench`. Setup/library scanning remains local. Core-backed commands use the same resolver and process helper as the tools. `/career-workbench` performs no provider/model call: it builds a bounded, visibly reviewable ordinary Pi editor prompt, and nothing leaves the package until the user separately submits that message through Pi. See [`product-flow.md`](product-flow.md) and [`application-workspaces.md`](application-workspaces.md).
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Runtime resolution and compatibility
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Runtime routes are resolved in this fixed order:
|
|
22
22
|
|
|
23
|
-
1.
|
|
24
|
-
2.
|
|
25
|
-
3.
|
|
23
|
+
1. a bounded absolute `CAREER_CLI_PATH`, when explicitly set;
|
|
24
|
+
2. the first executable `career` on the caller's `PATH`;
|
|
25
|
+
3. a package-local exact `@revazi/career@0.1.1` launcher;
|
|
26
|
+
4. bounded acquisition of exact `@revazi/career@0.1.1` from the canonical npm registry, followed by direct execution of the resolved launcher;
|
|
27
|
+
5. otherwise a stable payload-free installation error.
|
|
26
28
|
|
|
27
|
-
There is no
|
|
29
|
+
There is no sibling-checkout, Cargo, source-build, lifecycle-script, arbitrary URL/download, unpinned package, or PATH-selected npm/npx fallback. `PI_OFFLINE=1` disables route 4. The resolver caches only a successful route in process memory and invalidates it whenever the `CAREER_CLI_PATH` or `PATH` value changes.
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
`CAREER_CLI_PATH`, PATH, and package-local installations are caller-controlled. Before any private operation opens stdin, the selected route must pass the exact managed compatibility surface: Core version `0.1.1`, all 15 `career.operation_catalog.v1` descriptors (capability mapping, CLI path, transport, schema IDs, input bounds, and 32-MiB output bound), and the required self-contained schema bundles with only valid local references. Explicit override failure never falls back. Automatically considered routes may be skipped during this payload-free compatibility phase. If a previously selected automatic executable later fails before its operation process emits `spawn`, the adapter may advance once to the next route; cancellation, timeout, or any already-started operation is never retried through another route.
|
|
30
32
|
|
|
31
|
-
- `
|
|
32
|
-
- `linux-x64-gnu` (`x86_64-unknown-linux-gnu`, only when Node reports glibc)
|
|
33
|
+
The package-local and acquired routes execute the reviewed `@revazi/career` launcher using the real Node executable. Pi-career validates the exact v2 launcher manifest, ordered eight-package catalog reference, lockstep optional-package map, and bounded launcher file before execution. The launcher remains responsible for native package selection, libc requirements, package/version/provenance mapping, regular-file type, Unix mode or Windows file invariant, size, format, architecture, and SHA-256 verification before it starts Career Core. Pi-career does not duplicate those native verification algorithms or package native files.
|
|
33
34
|
|
|
34
|
-
Windows,
|
|
35
|
+
Acquisition invokes the npm CLI derived from the real `process.execPath` installation using the reviewed Unix or Windows Node installation layout, rejects ambiguous or conflicting `npm_execpath`, pins the canonical registry/package/version, includes optional native packages, and disables lifecycle scripts. It never invokes an npm/npx executable selected from caller `PATH`. Unix acquisition pins `/bin/sh`; Windows acquisition validates `SystemRoot`, derives `System32/cmd.exe`, rejects conflicting `ComSpec`, sanitizes shell/PATH overrides, and uses that shell only inside npm's acquisition-only execution. npm's acquisition command prints only its controlled PATH through Node's `-p` option. From bounded stdout, pi-career requires exactly one absolute first PATH entry ending in `node_modules/.bin`, derives the fixed sibling `@revazi/career/bin/career.js`, and ignores platform-specific npm banner lines without exposing them. It then invokes the manifest-validated JavaScript launcher directly with real Node and `shell: false`; no npm command shim becomes the Career route.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
Acquisition has fixed time/stdout/stderr bounds and sends no private stdin. The npm child starts in a detached process group: Unix cancellation signals the negative process-group ID, while Windows uses `CTRL_BREAK` for the detached npm group and a bounded forced pass for npm itself. Ordinary npm cache and `_npx` data may remain after acquisition; neither package removal nor `PI_OFFLINE=1` provides secure erasure.
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
The reviewed `@revazi/career@0.1.1` launcher supplies `darwin-arm64`, `darwin-x64`, `linux-x64-gnu`, `linux-arm64-gnu`, `linux-x64-musl`, `linux-arm64-musl`, `win32-x64-msvc`, and `win32-arm64-msvc`. GNU Linux requires glibc 2.35 or newer. Unknown targets/libc, older glibc, and native integrity failures remain delegated to that launcher and surface only as bounded adapter failures. Windows PATH discovery remains direct-argv-only and considers native `career.exe`/`.com`/extensionless files, not caller-selected `.cmd` or `.bat` shells; package launchers use the validated package-local/acquired route instead.
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
## Process and privacy boundary
|
|
41
42
|
|
|
42
|
-
The
|
|
43
|
+
The adapter calls `spawn(command, fixedArgv, { shell: false })`; operations and schema IDs are bounded before spawn. For package launcher routes, the fixed prefix is the validated launcher path invoked by the real Node executable. Document JSON is one bounded object string sent only through child stdin with `--input - --format json-compact`. Private stdin is not ended into the child until Node emits the successful `spawn` event.
|
|
44
|
+
|
|
45
|
+
The process adapter creates no payload/result temporary files and adds no model, provider, telemetry, repair, URL-fetching, or command retry after launch. The sole network-capable runtime behavior is the bounded exact-package acquisition above, which finishes before private stdin opens. A successful Core child must emit exactly one UTF-8 JSON object with no stderr. Raw tools retain the 50,000-byte/2,000-line Pi-context ceiling and fail without partial output. Managed execution captures the complete Core result up to Core's declared 33,554,432-byte successful-machine-output ceiling. Complete managed results and exact review inputs live only in a 16-entry/64-MiB process-memory registry addressed by ephemeral handles; session/branch replacement and shutdown clear private entries. Model-visible projections/details remain capped at 50,000 bytes and never truncate the authoritative Core result.
|
|
46
|
+
|
|
47
|
+
A direct Career Core operation timeout or abort sends `SIGTERM`, then `SIGKILL` after a bounded grace period, and settlement waits for close. npm acquisition uses detached process-group termination for descendants, including Windows `CTRL_BREAK` delivery rather than a PATH-selected tree-kill helper. stdout and stderr have independent byte ceilings. Fatal UTF-8, malformed/multiple success documents, successful stderr, signals, and stream failures map to stable errors. Only a strictly shaped, bounded, allowlisted `career.error.v1` may be nested in an adapter error. Source/result text, executable paths, hashes, platform/environment values, npm output, raw stderr, and filesystem/process errors are never logged or exposed.
|
|
48
|
+
|
|
49
|
+
The workflow may read configured `.pdf`/`.md`/`.txt` roots, atomically persist non-content global config—including one bounded preferred variation-directory suggestion—and append consented custom session entries. Searchable PDF text is extracted from bounded in-memory bytes in a package-owned worker with fixed page, time, result, and memory ceilings; network fetch is disabled before the parser loads. No full Core result is appended to session state or written to a file, and pi-career has no full-result file export.
|
|
43
50
|
|
|
44
51
|
## Threat model
|
|
45
52
|
|
|
46
53
|
| Threat | Mitigation |
|
|
47
54
|
|---|---|
|
|
48
55
|
| Shell or argument injection | Fixed allowlisted operation mappings, bounded schema-ID syntax, direct argv-only spawn, `shell: false`, document bytes on stdin only. |
|
|
49
|
-
| Executable substitution |
|
|
50
|
-
|
|
|
51
|
-
| Unsupported
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| Hidden external behavior | Workflow and runtime sources contain no fetch, provider, credential, telemetry, MCP, or model invocation. Commands invoke only the package-owned deterministic process helper. No-model/offline smokes enforce the surface. |
|
|
60
|
-
| Supply-chain or packaging drift | Exact Core source/run provenance, lockfile-pinned development tools, npm derived from the real Node installation instead of `PATH`, inherited `npm_execpath` verification, npm tree/severity environment sanitization, duplicate-key-rejecting bounded JSON, verified absolute system tar, four wildcard external peers, tracked deterministic bundle, runtime/package allowlists and limits, zero low-threshold production and full audits, native CI execution on each claimed target, and extracted isolated install acceptance. |
|
|
61
|
-
|
|
62
|
-
## Build, package, and CI boundary
|
|
63
|
-
|
|
64
|
-
`npm run build` rebuilds only `dist/index.js`; native artifacts are never built or downloaded implicitly. Runtime refresh requires a separate approved native artifact workflow and manifest review.
|
|
56
|
+
| Executable substitution | Fixed route order; bounded absolute override; exact managed compatibility before private stdin; pinned canonical npm package; package launcher native verification. |
|
|
57
|
+
| Malicious PATH/npm shadowing | PATH `career` remains caller-controlled and must pass compatibility. npm is derived from real Node, conflicting `npm_execpath` is rejected, and npm/npx is never selected from PATH. |
|
|
58
|
+
| Unsupported or corrupted native package | The reviewed launcher validates target/libc, package lockstep, provenance, Unix mode or Windows file invariant, size, format, architecture, and SHA-256 and fails before native execution. |
|
|
59
|
+
| Private input sent to multiple routes | Compatibility probes contain no private input. Only a failure before `spawn` may retry once; started, cancelled, and timed-out operations never retry. |
|
|
60
|
+
| Acquisition sees private content | Acquisition completes before document stdin opens and receives no document bytes. `PI_OFFLINE=1` disables it. |
|
|
61
|
+
| Hung acquisition descendants | Fixed acquisition timeout/output bounds, detached process groups, Unix group signals, and Windows `CTRL_BREAK` plus a bounded forced npm pass. |
|
|
62
|
+
| Oversized request, stream, diagnostic, memory, or context | Core-catalog input ceilings, independent stdout/stderr ceilings, fixed timeouts, raw context limits, 32-MiB managed capture, bounded registry, and 50,000-byte projections. |
|
|
63
|
+
| Private payload disclosure in failures | Payload-free adapter errors; no source/result/path/environment/raw-error logging; only validated Core error envelopes may be nested. |
|
|
64
|
+
| Persistence mistaken for erasure | Config contains no source/result content; managed results are process-memory-only; npm/Pi/session/cache data is explicitly not claimed to be securely erased. |
|
|
65
|
+
| Supply-chain or package drift | Exact external package coordinate, canonical registry, reviewed launcher delegation, four wildcard external Pi peers, no packaged runtime dependency/tree, deterministic dist, strict package allowlist, trusted npm/tar tooling, and clean low-threshold audits. |
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
## Build, package, CI, and installation boundary
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
`npm run build` rebuilds only `dist/index.js` and `dist/pdf-worker.js`; it never builds, imports, or downloads native artifacts. The pi-career tarball contains no `runtime/`, native binary, `node_modules`, or Pi peer contents and declares no production/optional runtime dependency. Runtime acquisition is an invocation-time resolver route, not an npm lifecycle action.
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
Package/audit orchestration invokes npm through `process.execPath` plus its derived absolute CLI and uses verified root-owned `/usr/bin/tar`, never PATH-selected npm/tar. Checks sanitize npm tree/severity overrides, reject duplicate decoded JSON keys, enforce exactly four wildcard external peers, verify extracted load/offline failure/install behavior, and require clean production/full audits at `--audit-level=low`. These Unix release gates remain separate from cross-platform runtime acceptance.
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
`test:career-package` separately exercises exact-package acquisition, managed Core 0.1.1 compatibility, and representative synthetic resume/job operations. The manually dispatched hosted External Career Compatibility workflow runs that acceptance natively for six release-gate targets: both macOS architectures plus GNU Linux x64/ARM64 and musl Linux x64/ARM64 in the exact pinned Alpine/Node container on native hosts. The macOS arm64 and Linux x64 GNU contexts run the complete release ladder; additional target jobs run build/type/runtime-boundary, exact-package, offline-load, and diff checks appropriate to their native environment. Ordinary pull requests run one required adapter job without external Career package acquisition; maintainers reserve the costly matrix for resolver/contract/platform changes and frozen releases.
|
|
73
74
|
|
|
74
|
-
`
|
|
75
|
+
A user may register a reviewed clean absolute local path, public Git URL pinned to a full reviewed commit, or exact `npm:pi-career` version. Installing pi-career does not install Career Core through a lifecycle script. At first Core use, a compatible explicit/PATH/package-local route is preferred; otherwise the exact package may be acquired unless offline. Removal unregisters pi-career but does not erase Pi sessions, shell history, npm cache, Git clones, backups, or separately saved results.
|
|
75
76
|
|
|
76
77
|
## Provenance
|
|
77
78
|
|
|
78
|
-
The initial process adapter, tool mappings, synthetic fake executable, process tests, and skill guidance were adapted from Career Core commit `100774ed8bb3b39c019d64ce105af1e3f209144f`.
|
|
79
|
+
The initial process adapter, tool mappings, synthetic fake executable, process tests, and skill guidance were adapted from Career Core commit `100774ed8bb3b39c019d64ce105af1e3f209144f`. Managed-contract support was aligned with Career Core Phase 8 commit `f6d17835de4817e28ce84e8e5734ff592687dfcc`. The exact Core 0.1.1/eight-target launcher update was reviewed from Career Core commit `0318b3b0993ee23093c8f023757fa7e4d8b3b8e0` and protected publication run `31346152236`. Native distribution and integrity authority belong to exact `@revazi/career@0.1.1`, not pi-career.
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Status and scope
|
|
4
4
|
|
|
5
|
-
This is reproducible dependency evidence for the two native `career` binaries
|
|
5
|
+
This is historical reproducible dependency evidence for the two native `career` binaries packaged by pi-career `v0.1.0` and its pre-external-resolver development candidate. Pi-career `v0.2.0` tracks and packages no native binary; native distribution evidence belongs to `@revazi/career`. This document is **not legal advice**, a legal-compliance conclusion, an SPDX/CycloneDX SBOM, or release approval.
|
|
6
6
|
|
|
7
7
|
The inventory is pinned to:
|
|
8
8
|
|
|
9
|
-
- Career Core commit [`
|
|
9
|
+
- Career Core commit [`f6d17835de4817e28ce84e8e5734ff592687dfcc`](https://github.com/revazi/career-core/tree/f6d17835de4817e28ce84e8e5734ff592687dfcc)
|
|
10
10
|
- Cargo.lock SHA-256 `18d188cfea79128d4024dabe2e21f57e5d2098d32ffac8c4ef01243f49abb609`
|
|
11
11
|
- package `career-cli 0.1.0`
|
|
12
12
|
- build edges `normal,build`, excluding development dependencies
|
|
13
13
|
- targets `aarch64-apple-darwin` and `x86_64-unknown-linux-gnu`
|
|
14
14
|
|
|
15
|
-
The per-target provenance records
|
|
15
|
+
The historical per-target provenance records showed the corresponding locked release builds:
|
|
16
16
|
|
|
17
17
|
```text
|
|
18
18
|
cargo build --release --locked -p career-cli --target aarch64-apple-darwin
|
|
@@ -21,7 +21,7 @@ cargo build --release --locked -p career-cli --target x86_64-unknown-linux-gnu
|
|
|
21
21
|
|
|
22
22
|
## Derivation
|
|
23
23
|
|
|
24
|
-
The
|
|
24
|
+
The original dependency graph was derived from a read-only Career Core export using the offline commands below. For Phase 8 commit `f6d1783`, the lockfile remains byte-identical at the pinned SHA-256 and the manifest diff adds ownership/publication metadata but no normal/build dependency; both new per-target provenance records retain the same locked Rust 1.97.1 release-build boundary.
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
cargo metadata --locked --offline \
|
|
@@ -47,8 +47,8 @@ For crates.io packages, “Source” identifies the immutable name/version regis
|
|
|
47
47
|
| `anstyle` | `1.0.14` | `MIT OR Apache-2.0` | [crates.io](https://crates.io/crates/anstyle/1.0.14) | `940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000` |
|
|
48
48
|
| `anstyle-parse` | `1.0.0` | `MIT OR Apache-2.0` | [crates.io](https://crates.io/crates/anstyle-parse/1.0.0) | `52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e` |
|
|
49
49
|
| `anstyle-query` | `1.1.5` | `MIT OR Apache-2.0` | [crates.io](https://crates.io/crates/anstyle-query/1.1.5) | `40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc` |
|
|
50
|
-
| `career-cli` | `0.1.0` | `MIT OR Apache-2.0` | [Core workspace](https://github.com/revazi/career-core/tree/
|
|
51
|
-
| `career-core` | `0.1.0` | `MIT OR Apache-2.0` | [Core workspace](https://github.com/revazi/career-core/tree/
|
|
50
|
+
| `career-cli` | `0.1.0` | `MIT OR Apache-2.0` | [Core workspace](https://github.com/revazi/career-core/tree/f6d17835de4817e28ce84e8e5734ff592687dfcc/crates/career-cli) | commit-bound |
|
|
51
|
+
| `career-core` | `0.1.0` | `MIT OR Apache-2.0` | [Core workspace](https://github.com/revazi/career-core/tree/f6d17835de4817e28ce84e8e5734ff592687dfcc) | commit-bound |
|
|
52
52
|
| `clap` | `4.6.4` | `MIT OR Apache-2.0` | [crates.io](https://crates.io/crates/clap/4.6.4) | `d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7` |
|
|
53
53
|
| `clap_builder` | `4.6.2` | `MIT OR Apache-2.0` | [crates.io](https://crates.io/crates/clap_builder/4.6.2) | `f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b` |
|
|
54
54
|
| `clap_derive` | `4.6.4` | `MIT OR Apache-2.0` | [crates.io](https://crates.io/crates/clap_derive/4.6.4) | `d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061` |
|