pi-career 0.3.0 → 0.4.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Status
4
4
 
5
- Career Core Phase 8 was merged as `f6d1783` through PR #21. The compact `career_run` implementation, ephemeral handles, complete bounded in-memory results, detail hydration, raw-tool activation control, synthetic token benchmark, and bounded non-PDF reviewed-change selector are implemented here. Runtime distribution now belongs to reviewed exact `@revazi/career@0.2.0`; pi-career packages no native artifacts, supports only macOS/Linux, and resolves compatible external routes before managed execution. Synthetic PDF compatibility covers reviewed Chromium-generated tagged and untagged documents, a reproducible ReportLab-generated two-page document, an embedded open-licensed font, a CSS multi-column layout, and fail-closed image-only/malformed/oversized inputs. The package-owned user-confirmed materialized-variant save workflow is implemented for private Markdown/text artifacts on those supported platforms. The dedicated token-optimization benchmark study now has frozen before/after evidence bound to the reviewed production commits and exact source/Skill trees. Full application workspaces, further review UX, and further PDF generator/font coverage remain later explicitly authorized work; Windows is unsupported rather than deferred roadmap scope.
5
+ Career Core Phase 8 was merged as `f6d1783` through PR #21. The compact `career_run` implementation, ephemeral handles, complete bounded in-memory results, detail hydration, raw-tool activation control, synthetic token benchmark, and bounded non-PDF reviewed-change selector are implemented here. Runtime distribution now belongs to reviewed exact `@revazi/career@0.2.0`; pi-career packages no native artifacts, supports only macOS/Linux, and resolves compatible external routes before managed execution. Synthetic PDF compatibility covers reviewed Chromium-generated tagged and untagged documents, a reproducible ReportLab-generated two-page document, an embedded open-licensed font, a CSS multi-column layout, and fail-closed image-only/malformed/oversized inputs. The package-owned user-confirmed materialized-variant save workflow is implemented for private Markdown/text artifacts on those supported platforms. Application-workspace Gate 1 is also implemented for explicit config-v2 migration, one disjoint private root, immutable application status/vacancy/selected-original revisions, and read-only reconciliation. The dedicated token-optimization benchmark study now has frozen before/after evidence bound to the reviewed production commits and exact source/Skill trees. Application-workspace assisted artifacts, deletion, repair/adoption/archive/sync and broader files, further review UX, and further PDF generator/font coverage remain later explicitly authorized work; Windows is unsupported rather than deferred roadmap scope.
6
6
 
7
7
  Completed sequence:
8
8
 
@@ -15,9 +15,35 @@ Completed sequence:
15
15
  7. Turn-terminating variant review plus bounded TUI warning/discard review, exact change inspection, explicit selection, and later editor handoff without automatic materialization.
16
16
  8. User-only TUI/RPC exact preview and confirmed no-clobber saving of current POSIX Markdown/text materializations with fail-closed assisted sidecars and rescanning.
17
17
  9. Versioned pre-optimization token benchmark with immutable Git source/Skill-tree and snapshot provenance, actual contracts and managed serialization parity, Skill discovery/full-load context, call/result/detail/editor surfaces, independent workflow rollups, semantic-retention invariants, and explicit before/optimizing/after gates.
18
+ 10. User-only application-workspace Gate 1 with strict config v2/CAS, one existing private disjoint root, immutable application state/vacancy/original bindings, and read-only reconciliation without Core/provider/model/network/session-append behavior.
18
19
 
19
20
  This document records findings and phase boundaries; it does not independently authorize persistence, publication, release, or later deferred work.
20
21
 
22
+ ## Next target: model context on demand
23
+
24
+ The completed optimization reduced the cost of an activated Career workflow. The application-overlay phase has a stricter goal: a model turn in an ordinary Pi session that has not been explicitly activated for Career assistance must contain **zero Career-specific context tokens**. No `career-core` Skill name/description/content and no `career_run` or raw-tool schema should be model-visible merely because pi-career is installed. This target replaces neither the bundled Skill nor the managed tool; it changes when they become model-visible.
25
+
26
+ The activation contract is:
27
+
28
+ 1. `/career` navigation, local catalog/detail reads, readiness derivation, and deterministic Career Core Analyze/Match actions do not activate model context and do not submit a model turn.
29
+ 2. Only a user-selected assistance action such as resume regeneration, cover-letter suggestions, or match explanation may request Career model context.
30
+ 3. The adapter first revalidates the selected application and prepares a visible bounded editor handoff. It never submits that handoff automatically.
31
+ 4. The bundled Career Skill and compact `career_run` tool become available only to the explicit application-scoped assistance session. `career_run` remains the primary managed tool.
32
+ 5. Once activated, that session keeps a stable Career model surface across its related turns so prompt caching is not defeated by per-turn tool/Skill churn.
33
+ 6. The exact raw compatibility names—`career_core_discover`, `career_core_resume`, and `career_core_job`—remain registered compatibility surfaces but inactive unless the user explicitly selects raw/debug mode.
34
+ 7. `/new`, branch replacement, detach, application identity drift, and unavailable roots invalidate process-local handles and require fresh validation. No prior application context is silently reused.
35
+
36
+ Application attachment and model-context activation are separate. #64 fixes the exact strict custom-entry data in [`application-workspaces.md`](application-workspaces.md): one path-free root/application identity pointer, an exact detachment record, and a separate activation bound to that attachment. Implementation removes static Skill discovery, reconstructs valid activation in `session_start`, conditionally contributes the bundled Skill path from `resources_discover`, activates only `career_run`, and uses one terminal reload after activation, detach, or a branch visibility change. It must follow Pi’s fresh-session lifecycle and never retain an old context after session replacement.
37
+
38
+ Benchmarking for this target must keep the historical frozen optimization evidence unchanged and add separate measurements for:
39
+
40
+ - ordinary model turns outside an explicitly activated Career assistance session: exactly zero Career-specific Skill/tool tokens;
41
+ - overlay and deterministic local operations: zero model submissions and zero model tokens;
42
+ - first activated assistance turn: Skill discovery/content, `career_run`, handoff, and bounded result surfaces; and
43
+ - later turns in the same assistance session: an unchanged model-visible Career surface suitable for provider prompt-cache reuse.
44
+
45
+ This target does not authorize removal of `career_run`, renaming of raw tools, hidden prompt submission, automatic session creation, or implementation before the persistence/session contracts are approved.
46
+
21
47
  ## Findings motivating the migration
22
48
 
23
49
  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:
@@ -162,7 +188,7 @@ Raw generic agents remain discovery-first. A reviewed managed adapter may perfor
162
188
 
163
189
  ## Pi-career managed adapter phase
164
190
 
165
- 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.
191
+ The current implementation 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. The context-on-demand target above will additionally keep `career_run` and Career Skill metadata out of model turns outside an explicitly activated assistance session while preserving this managed/raw relationship after activation.
166
192
 
167
193
  ### Ephemeral handles
168
194
 
@@ -217,7 +243,7 @@ The implemented design and threat model are recorded in [`variant-save-workflow.
217
243
  6. immutable originals and overwrite rejection
218
244
  7. immediate library rescan with variants excluded from authoritative analysis/matching
219
245
 
220
- Destination configuration remains suggestion-only until one exact `/career-save` plan is previewed unchanged and separately confirmed. Full-result export and application-workspace persistence remain outside this narrower materialized-variant save workflow.
246
+ Destination configuration remains suggestion-only until one exact `/career-save` plan is previewed unchanged and separately confirmed. Full-result export and `/career-workspace` remain outside this narrower materialized-variant save workflow; Gate 1 application state persistence is a separate user-only consent surface, while assisted workspace artifacts and deletion remain later gates.
221
247
 
222
248
  ### Document ingestion
223
249
 
@@ -0,0 +1,18 @@
1
+ # Application-owned cover letters — issue #57
2
+
3
+ This contract authorizes only user-authored Markdown or UTF-8 plain-text cover-letter artifacts in the application workspace. It does not authorize provider/model drafting, adoption of files, submission, or deletion.
4
+
5
+ ## Authority and state
6
+
7
+ The canonical `pi.career.application_state` schema retains its nullable `cover_letter_artifact` reference. A non-null reference binds a private application-owned relative path, SHA-256, UTF-8 byte size, format, `authority: "user_authored"`, current vacancy digest, and effective-resume digest. Readiness remains derived from the complete validated state chain and current dependencies; a missing, stale, drifted, or unavailable reference is not ready.
8
+
9
+ Artifacts are immutable revisions named `cover-letter-NNNNNN.md` or `.txt`; edits create a new artifact and state revision and never modify prior artifact bytes. View opens the validated current artifact in local UI only. Clear appends a state revision with a null reference and does not remove artifact history.
10
+
11
+ ## Write transaction
12
+
13
+ 1. Require the currently attached, valid application and both a current vacancy and effective resume. Ask the user to select Markdown or plain text, then author content in a local editor. Input must be valid UTF-8, non-empty, CR-free, NUL-free, and no larger than the existing 262,144-byte workspace text bound.
14
+ 2. Display the exact authored bytes in a separate preview editor. Require unchanged return, then require a distinct persistence confirmation. Cancellation at either step writes nothing.
15
+ 3. Build a path-free mutation preview and obtain the existing explicit workspace mutation approval. Under the application-root lock, revalidate config snapshot, attached application identity, current application parent hash (which binds the expected previous cover-letter reference), vacancy/resume authority, capacity, and absence of every target.
16
+ 4. Publish artifact then state using the existing private temporary-file, exclusive/no-clobber publication protocol; state is the commit record. On failure, rollback only files proven to be owned by this transaction. Unknown pre-existing files fail closed and are never overwritten/adopted. A state append is never reported successful unless its committed head is verified.
17
+
18
+ All data remains local to the configured application workspace and local Pi UI. No Core/provider/network calls or session payload appends occur. Errors remain payload-free. Clearing and editing preserve the complete immutable artifact history.
package/docs/design.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
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 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:
7
+ In the current command-oriented implementation, 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`
@@ -14,10 +14,28 @@ The primary managed Pi surface is `career_run`. It uses ephemeral resume/result/
14
14
 
15
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 and declares only macOS/Linux installation through `os: ["darwin", "linux"]`.
16
16
 
17
- The workflow layer registers `/career-setup`, `/career-library`, `/career-application`, `/career-vacancy`, `/career-match`, `/career-analyze`, `/career-workbench`, the TUI-only `/career-review`, and the user-only TUI/RPC `/career-save`. 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. `/career-review` also invokes neither Core nor a provider; it reads one current in-memory non-PDF variant review, collects explicit canonical IDs after warning/discard and exact-change inspection, and prepares a later editor message containing only the handle and IDs. See [`product-flow.md`](product-flow.md) and [`application-workspaces.md`](application-workspaces.md).
17
+ The workflow layer registers `/career`, `/career-setup`, `/career-library`, `/career-application`, `/career-vacancy`, `/career-match`, `/career-analyze`, `/career-workbench`, `/career-workspace`, the TUI-only `/career-review`, and the user-only TUI/RPC `/career-save`. Those `/career*` view commands open one view model; TUI overlay and RPC dialogs only render it. Application-workspace Gate 1 owns only explicit config-v2 migration, one private disjoint application root, immutable manifest/state/vacancy/original bindings, and read-only reconciliation; assisted workspace artifacts and deletion remain unimplemented later gates. Application state has one approved schema, [`pi.career.application_state`](single-application-state.md); append-only revision numbers remain integrity/history controls rather than schema versions, and former state `.v1`/`.v2` identifiers fail closed without migration. Setup/library scanning remains local. Core-backed `career_run` uses the same resolver and process helper as before. `/career-review` also invokes neither Core nor a provider; it reads one current in-memory non-PDF variant review, collects explicit canonical IDs after warning/discard and exact-change inspection, and prepares a later editor message containing only the handle and IDs. See [`product-flow.md`](product-flow.md) and [`application-workspaces.md`](application-workspaces.md).
18
18
 
19
19
  The user-only `/career-save <variant-handle>` workflow is specified in [`variant-save-workflow.md`](variant-save-workflow.md). It accepts only a current successful non-PDF materialization, uses supported Pi TUI/RPC editor and confirmation dialogs, and writes nothing until the exact preview is returned unchanged and separately confirmed. Saving performs no Core/provider/network call, appends no session entry, and preserves all runtime-resolution, private-stdin, registry, and payload-free error boundaries in this document.
20
20
 
21
+ A separate local-only document preview action is available after opening eligible library-original or attached vacancy/selected-original/effective-Resume metadata detail. It freshly revalidates the selected authority and text digest, rejects unsafe or >12,000-byte text without truncation, and displays only validated text in transient TUI/RPC UI (TUI paginates six exact soft-wrapped lines at a time; if a grapheme cannot fit in the current terminal width, it displays no partial body and asks the user to widen the terminal; RPC shows the complete bounded text). The RPC `ui.select` title carries those private bytes to the local UI client, which may retain UI payloads under the existing [RPC local-UI retention boundary](application-workspaces.md); this is not a model prompt or provider send. Back/cancel clears the preview buffer in pi-career, not any client-held copy; list rows, ordinary detail, result cards, notifications, session entries, model context, and errors do not receive the body. This does not activate Career assistance, call Core, send to a provider, or mutate files or sessions. A tailored effective Resume remains labeled assisted, not original. The Gate 1 application-workspace contract is specified in [`application-workspaces.md`](application-workspaces.md). Every local mutation requires a complete unchanged editor preview and separate confirmation, uses strict private config/root/file validation and bounded lock/no-clobber settlement, and performs no Core/runtime/provider/model/network/child/session-append action. Empty `/career-workspace` opens the shared Career view rather than that mutation menu.
22
+
23
+ ## `/career` overlay and context boundary
24
+
25
+ One Career view model owns routes, items, selection, detail, and actions. Applications and Resumes are the only peer top-level destinations. Setup is contextual to Resumes; job description, Analyze, Match, Workspace, and Ask Pi are contextual to application/Resume state. The existing `/career-setup`, `/career-library`, `/career-application`, `/career-vacancy`, `/career-match`, `/career-analyze`, `/career-workbench`, and `/career-workspace` names remain direct routes into that hierarchy. A contextual route has an explicit breadcrumb and Back/Escape parent, while destination switching exposes only Applications and Resumes in both TUI and RPC.
26
+
27
+ The Applications projection preserves catalog ordering, adds process-local text and lifecycle filters, opens a valid attached application directly in detail, and renders lifecycle plus the derived three-component readiness projection without persisting a second index or readiness state. Current state, the derived recommended next action, and safe alternatives are visible in application detail and empty/prerequisite states; recommendations never execute themselves. Only the exact attached application exposes its contextual package actions, lifecycle mutation, and detach; marking an incomplete package Applied adds a separate warning and never claims employer submission or changes readiness. The TUI overlay and RPC hierarchical select/confirm dialogs are only renderers of that model. `/career` is local application code and never a model tool.
28
+
29
+ The TUI renderer owns a complete theme-compatible rounded Unicode modal frame with connected separators, one column of interior padding on both sides, and explicit host margin around the centered overlay. Every ANSI/Unicode header, breadcrumb, destination, list/detail, exact-preview, and contextual-footer line is measured against the reduced inner width before the outer border is added. The component derives its maximum row count from Pi's terminal and preserves the frame, destinations, and footer while scrolling only the content viewport; long catalogs keep the selected row visible, and detail/help use Up/Down scrolling. Widths below 60 columns or viewports below 18 available rows reveal no private preview body and return only bounded resize guidance; action, navigation, and help keys remain inactive there, while Escape retains safe Back/Close or operation-cancellation behavior. Selection and active destination use visible glyph/text state rather than color alone; footer hints show a recommended action plus a bounded set of alternatives, and local help exposes the complete eligible shortcut list without performing an action.
30
+
31
+ Opening, highlighting, browsing, filtering, switching destinations, help, and viewing local details must not attach an application, bind a Resume, activate assistance, call `sendMessage()` or `sendUserMessage()`, invoke a provider/model, append a session entry, resolve/acquire/invoke Core, or mutate a file. Attach, library root add/remove/rescan, application create, selected-original bind, vacancy edit/clear, status update, detach, Ask Pi, and workspace management are explicit actions on the same model. Attached selected-original bind reuses the exact immutable workspace preview, confirmation, fresh-source validation, and no-clobber commit path; attached Analyze and Match require that authority instead of selecting an unrelated library original. Explicit deterministic Analyze and Match actions invoke Core through the unchanged resolver boundary, but do not activate or invoke a model. In the Resume-library detail, Analyze is available only for the highlighted available Original; the action carries that record's exact document/root/format/text-digest identity through post-confirmation rescan and final submission validation, never reopening the generic chooser or substituting another Resume. Library detail also exposes explicit authority, format, availability, current-session analysis state, and payload-free notices. Explicit Rescan presents local cancellable progress and installs only a completed projection; root removal remains a separately confirmed config-only change.
32
+
33
+ The overlay reads one bounded catalog metadata snapshot per open or explicit refresh, loads exact document/detail bytes lazily, and caches only bounded process-local view data. It creates no index, watcher, polling task, payload/result persistence, or speculative operation. Every mutation, Core action, attachment, and assistance handoff revalidates current identity and referenced bytes rather than trusting cached display state.
34
+
35
+ The target model surface is context-on-demand. Installation and ordinary model turns outside an explicitly activated Career assistance session expose no Career-specific Skill metadata/content or tool schema. Only an explicit assistance action may establish one application-scoped assistance session, load the bundled Career Skill, and activate the primary `career_run` tool; the exact raw compatibility tools remain inactive by default. The action may prepare a visible editor handoff but may not submit it. Once the user submits, the activated Career surface remains stable within that assistance session for prompt-cache reuse.
36
+
37
+ Application attachment is a separate #64 decision with exact path-free identity-pointer, detachment, and activation custom-entry data specified in [`application-workspaces.md`](application-workspaces.md). Attachment contains no document/result/prompt content and does not itself activate tools, load Skill content, invoke Core/provider, or authorize persistence. Workspace files remain authoritative. The implemented lifecycle removes static Skill discovery, validates branch state in `session_start`, contributes the Skill path conditionally in `resources_discover`, and terminally reloads after visibility changes. It does not authorize publication or release.
38
+
21
39
  ## Runtime resolution and compatibility
22
40
 
23
41
  At extension initialization, pi-career requires macOS or Linux. Any other platform, including Windows, registers no command or tool and returns one stable payload-free `unsupported_platform` adapter error before reading or validating `CAREER_CLI_PATH`, traversing `PATH`, checking a package-local launcher, acquiring npm content, invoking a compatibility probe, or opening private stdin. Invocation and resolver entry points retain the same guard as defense in depth. On a supported platform, runtime routes are resolved in this fixed order:
@@ -30,7 +48,7 @@ At extension initialization, pi-career requires macOS or Linux. Any other platfo
30
48
 
31
49
  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.
32
50
 
33
- `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.2.0`, 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.
51
+ `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.2.0`, 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. Probe failures, including cancellation and timeout, are reissued as stable payload-free adapter errors and do not retain foreign messages, stacks, paths, environment values, or validated Core error text. 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.
34
52
 
35
53
  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 six-package catalog reference, lockstep optional-package map, declared file allowlist, `career` bin, and bounded launcher file before execution. The launcher remains responsible for native package selection, libc requirements, package/version/provenance mapping, regular-file type and Unix mode, 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.
36
54
 
@@ -48,7 +66,7 @@ The process adapter creates no payload/result temporary files and adds no model,
48
66
 
49
67
  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 Unix process-group termination for descendants 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.
50
68
 
51
- 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. `/career-save` may persist only exact current assisted Markdown/text materialization bytes plus bounded package-owned marker/sidecar metadata after file-specific approval.
69
+ The workflow may read configured `.pdf`/`.md`/`.txt` roots, compare-and-swap canonical non-content global config—including one bounded preferred variation-directory suggestion and an optional application-root UUID/path binding—and append consented custom session entries. Config v1 is never migrated at startup or by ordinary setup/library/variation mutations: absent or v1 config remains canonical v1 while `application_workspace` is logically null. Only the confirmed `/career-workspace` **Configure application root** mutation writes strict v2; every later writer preserves v2 and freshly enforces physical two-way disjointness when an application root is attached. First ordinary setup may safely bootstrap only the package `career/` directory beneath an existing canonical agent directory, while workspace configuration requires that private directory already exist. 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. `/career-save` may persist only exact current assisted Markdown/text materialization bytes plus bounded package-owned marker/sidecar metadata after file-specific approval. Workspace Gate 1 may separately persist only its non-content marker/manifest, append-only full state revisions, exact explicitly approved workflow-original vacancy snapshots, and selected-original digest binding.
52
70
 
53
71
  ## Threat model
54
72
 
@@ -66,6 +84,7 @@ The workflow may read configured `.pdf`/`.md`/`.txt` roots, atomically persist n
66
84
  | 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. |
67
85
  | Automatic, ambiguous, or stale review selection | Variant review terminates the turn; exact warnings/discards and per-change evidence are paged locally; all IDs default excluded; selected exact records receive a compact labeled final cross-change review, direct read-only reopening, and a separate prepare-or-back choice; only confirmed canonical IDs in Core order enter a later editor message; stale/PDF handles fail closed. |
68
86
  | Unapproved or unsafe local variant persistence | Save is user-only, requires exact unchanged preview plus separate confirmation, forbids overwrite, publishes private sidecar-first pairs, and requires fail-closed rescanning before success. |
87
+ | Agent-initiated or cross-root application persistence | `/career-workspace` is user-only and absent from tools; Gate 1 requires no arguments, exact preview plus separate confirmation, strict session UUID identity, physically disjoint private roots, immutable no-clobber revisions, and read-only reconciliation. |
69
88
  | Persistence mistaken for erasure | Config contains no source/result content; managed results and live selector state are process-memory-only; a user-submitted prepared editor message may enter the Pi session; npm/Pi/session/cache data and any separately approved future artifacts are explicitly not claimed to be securely erased. |
70
89
  | 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. |
71
90
 
@@ -0,0 +1,15 @@
1
+ # Product hardening validation
2
+
3
+ This is a test-evidence index, not a release authorization or claim of production-wire acceptance. Coverage uses synthetic documents, labels, sessions, and temporary workspaces only.
4
+
5
+ ## Black-box evidence
6
+
7
+ - Terminal presentation and navigation: `tests/workflow/overlay.test.mjs` checks Unicode/theme output at widths 8–120, TUI output at 32/48/80, visible wide-screen navigation hints, keyboard movement, and Escape cancellation. `tests/workflow/document-preview.test.mjs` checks bounded paging and preview clearing.
8
+ - TUI/RPC parity and discoverability: the overlay suite exercises registered commands in both modes, confirmation gates, and no-Core browsing; `tests/workflow/application-concurrency-acceptance.test.mjs` and `tests/workflow/lifecycle-restore-acceptance.test.mjs` cover persisted authority and restart behavior.
9
+ - Collections and resource bounds: `tests/workflow/application-catalog.test.mjs` browses 128 valid synthetic applications and verifies deterministic order and byte-for-byte non-mutation. `tests/workflow/capacity-boundary-matrix.test.mjs` covers root and per-application entry/byte limits; `tests/workflow/scan.test.mjs` covers bounded resume-library collections.
10
+ - Privacy and failure behavior: `tests/workflow/no-automatic-provider-submission.test.mjs`, `tests/workflow/no-private-sentinel-persistence.test.mjs`, and `tests/workflow/payload-free-error-boundaries.test.mjs` instrument forbidden provider/Core/session effects, private sentinels, and stable public failures.
11
+ - Restart, transient-session, branch, lock, crash, and drift cases are exercised by the lifecycle, attachment, concurrency, and workspace acceptance suites under `tests/workflow/`.
12
+
13
+ ## Limitations
14
+
15
+ These tests provide synthetic local evidence only; they do not establish real-user usability, behavior in every terminal emulator during an actual live resize, production network acceptance, or secure erasure. The 128-application check asserts bounded collection size and deterministic behavior, not a wall-clock SLA. The 0.4.0 candidate's fixture-backed compatibility run passed against the exact reviewed Career Core `v0.2.0` checkout at commit `536690632884c17336cc3c108f1bba0f254b862b`; that is local fixture parity, not production-wire acceptance. Production and full audits plus `check:publish` passed for the prepared candidate with the exact Pi 1.0.2 development suite: its published coding-agent package removes the root shrinkwrap that selected vulnerable `brace-expansion@5.0.9` in 1.0.0 and directly requires `brace-expansion@5.0.12`. This remediates the #149 dependency blocker without an audit baseline, lockfile workaround, policy exception, or claim of release authorization.