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.
@@ -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
- # Self-contained package design and threat model
1
+ # External-runtime adapter design and threat model
2
2
 
3
3
  ## Scope and authority
4
4
 
5
- `pi-career` is a self-contained Pi package in a publicly readable Git repository on two reviewed native targets. It owns the Pi extension, package-owned native runtime artifacts and resolver, Pi-facing Agent Skill, package/build tests, and installation guidance. Career Core remains authoritative for operations, schemas, algorithms, errors, evidence, warnings, uncertainty, ordering, and assisted/non-authoritative semantics; this repository does not reimplement those contracts in TypeScript.
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 stable Pi surface is exactly:
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
- The TypeScript source is authoritative. A checked-in deterministic `dist/index.js` supports clean local, pinned-Git, and npm Pi loading without development dependencies. Pi-provided imports remain external peers. Reviewed native artifacts are tracked directly in every package channel so installation needs no lifecycle script, Cargo, Rust, system `career` executable, or post-install runtime download. Package metadata permits only reviewed public publication of the unscoped `pi-career` package to the canonical npm registry.
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 deterministic workflow layer additionally registers `/career-setup`, `/career-library`, `/career-vacancy`, `/career-match`, and `/career-analyze`. These commands call the shared `invokeCareerCli` helper directly; they never route through an LLM-facing tool, provider, model, network, PATH, Cargo, sibling checkout, or downloaded runtime. See [`product-flow.md`](product-flow.md) for the phase boundary.
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
- ## Runtime provenance and selection
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
- [`../runtime/manifest.json`](../runtime/manifest.json) pins unsigned artifacts from Career Core commit `a3cdb4c6d7f966397e93ea4664071975bca7228c` and native artifact run [30953471793](https://github.com/revazi/career-core/actions/runs/30953471793). It records exact binary/provenance paths, target triples, sizes, modes, SHA-256 values, source archive identities, shared notices, and bounded capabilities/schema/representative-operation digests. Imported per-target provenance remains package-bounded.
19
+ ## Runtime resolution and compatibility
20
20
 
21
- Resolution order is fixed:
21
+ Runtime routes are resolved in this fixed order:
22
22
 
23
- 1. A bounded absolute `CAREER_CLI_PATH`, when explicitly set for reviewed development/recovery use.
24
- 2. The verified package-owned binary for the current supported target.
25
- 3. Otherwise a stable payload-free failure.
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 PATH, Cargo, sibling-checkout, download, npm platform-package, or install-script fallback.
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
- Supported targets are exactly:
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
- - `darwin-arm64` (`aarch64-apple-darwin`)
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, macOS x64, Linux arm64, Linux musl, and unknown libc/platform combinations fail closed as `unsupported_platform`.
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
- Before the first bundled spawn per process, the resolver rejects symlinks/non-files, requires exact `0755` mode and size, reads the bounded binary, and verifies SHA-256. Only successful verification is cached in memory. Selection/integrity errors expose no platform details, paths, hashes, environment values, or raw filesystem failures.
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
- ## Process boundary
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
- The adapter calls `spawn(executable, argv, { shell: false })`; operations and schema IDs are bounded before spawn. Document JSON is one bounded object string sent only through child stdin with `--input - --format json-compact`.
41
+ ## Process and privacy boundary
41
42
 
42
- The process adapter creates no payload/result temporary files and adds no network, model, provider, telemetry, repair, retry, or URL-fetching behavior. The workflow layer may read configured `.md`/`.txt` roots, atomically persist non-content global config, and append consented custom session entries, but it does not change the child-process boundary. A successful child must emit exactly one UTF-8 JSON object, no stderr, and a complete result within capture and Pi-context ceilings. Authoritative output is never truncated. Oversized results fail without partial output; pi-career has no full-result export.
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 | Override is explicit, absolute, and bounded. Default runtime path is package-fixed; no PATH/sibling/Cargo fallback exists. |
50
- | Bundled artifact corruption or target swap | Exact runtime allowlist, regular-file and executable-mode checks, target binary magic, manifest/provenance/source-run lock, size and SHA-256 verification before first spawn. |
51
- | Unsupported platform/libc guessed as compatible | Exact platform/arch selection and positive glibc detection; every other combination fails `unsupported_platform`. |
52
- | Oversized request, stream, diagnostic, or context | UTF-8 byte bounds before spawn, independent stdout/stderr ceilings, fixed timeout, 50,000-byte/2,000-line complete-result limits, fail closed without truncation. |
53
- | Hung or cancelled child | Abort propagation and fixed timeout send `SIGTERM`, then `SIGKILL` after a bounded grace period; settlement waits for close. |
54
- | Malformed, ambiguous, or multiple output documents | Fatal UTF-8 decoding and exact-one-object JSON validation. |
55
- | Private payload disclosure in failures | Raw stderr, process/filesystem errors, input/output, paths, hashes, platform details, and environment values never cross adapter errors or logs. Only strictly shaped, bounded, allowlisted `career.error.v1` values may be nested. |
56
- | Workflow persistence leaks or races | Global config contains canonical roots/labels only, uses a `0700` directory and atomic `0600` file, and never stores source text or Core output. Session state uses branch-aware custom entries excluded from LLM context; full Core JSON is never stored. |
57
- | Pi session persistence mistaken for adapter persistence | Persisted workflow sessions require the exact local-persistence decision before private vacancy or card entries. Transient sessions receive a notice. This is not secure erasure and local-session approval is not provider consent. |
58
- | Adapter changes Core authority | Successful JSON is returned complete and unchanged apart from removing one framing newline. Discovery-first skill guidance preserves evidence, warnings, uncertainty, baseline boundaries, and assisted labels. |
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
- Package checks allow only reviewed docs, extension/skill files, and the eight runtime files. They invoke npm through `process.execPath` plus its derived absolute CLI and invoke verified root-owned `/usr/bin/tar`, never a PATH-selected npm/tar. They enforce the exact public npm registry/access metadata, compressed/unpacked bounds, modes, hashes, provenance, no packaged `node_modules` or Pi package contents, no package-owned runtime npm dependencies, exactly four wildcard external peers, and no lifecycle or publication scripts. The extracted package must load, execute the current target with `CAREER_CLI_PATH` unset and an empty `PATH`, and pass an isolated Pi install/list/remove smoke.
67
+ ## Build, package, CI, and installation boundary
67
68
 
68
- Hosted CI uses native Ubuntu x64 GNU and macOS arm64 runners. Both run the tracked-dist stale gate, process/runtime/audit tests, complete artifact/package checks, real bundled discovery and representative resume/job operations, no-model load, isolated install, strict low-threshold `audit:production`, and the authoritative readiness-only `check:publish`. The latter is a direct Node orchestrator rather than nested npm scripts and requires clean production and full development/host-Pi audits. Both remove omit/include/audit-level/`NODE_ENV` overrides and strictly reject duplicate decoded JSON keys; no audit-acceptance baseline is allowed. Hosted tests require no separate Core checkout or provider credential.
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
- ## Installation boundary
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
- A normal supported-target user registers a reviewed clean absolute local path, the public Git URL pinned to a full reviewed commit, or `npm:pi-career` pinned to an exact reviewed version. Pi local paths follow changing files; pinned Git refs and npm versions require an explicit new coordinate. Removal only unregisters the package and does not erase Pi sessions, shell history, backups, or separately saved results.
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
- `CAREER_CLI_PATH` is not an onboarding requirement. A caller choosing it assumes review/compatibility responsibility for that executable; the same argv/stdin, bounds, cancellation, and error boundary still applies.
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`. Bundled runtime artifacts and their metadata were imported from exact Core commit `a3cdb4c6d7f966397e93ea4664071975bca7228c` via the reviewed native artifact run. This repository preserves the applicable `MIT OR Apache-2.0` terms and package-bounded notices in `NOTICE` and `runtime/`.
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 tracked by pi-career. It is **not legal advice**, a legal-compliance conclusion, an SPDX/CycloneDX SBOM, or release approval. A human license review remains mandatory under [`releasing.md`](releasing.md).
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 [`a3cdb4c6d7f966397e93ea4664071975bca7228c`](https://github.com/revazi/career-core/tree/a3cdb4c6d7f966397e93ea4664071975bca7228c)
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 show the corresponding locked release builds:
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 Career Core checkout was treated as read-only. The exact commit was exported to a temporary directory outside both repositories; the temporary export was removed after these offline commands:
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/a3cdb4c6d7f966397e93ea4664071975bca7228c/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/a3cdb4c6d7f966397e93ea4664071975bca7228c) | commit-bound |
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` |