pi-career 0.3.0 → 0.4.1

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.
@@ -1,8 +1,67 @@
1
1
  # Product flow roadmap
2
2
 
3
- The cross-repository migration plan and measured findings are recorded in [`career-run-roadmap.md`](career-run-roadmap.md). Career Core Phase 8, the first managed `career_run` implementation, and the threat-reviewed package-owned Markdown/text save workflow in [`variant-save-workflow.md`](variant-save-workflow.md) are complete. Synthetic PDF compatibility covers reviewed Chromium-generated tagged/untagged and ReportLab-generated two-page documents, embedded-font and multi-column layouts, and fail-closed text-unavailable cases. The Git-history/tree/hash-bound token-optimization study is complete: its frozen before/after evidence includes Pi Skill discovery and matching-task full-Skill context and records a 15.98% aggregate workflow reduction with no workflow regression. Full application-workspace persistence and further PDF extraction expansion remain later phases.
3
+ The cross-repository migration plan and measured findings are recorded in [`career-run-roadmap.md`](career-run-roadmap.md). Career Core Phase 8, the first managed `career_run` implementation, the threat-reviewed package-owned Markdown/text save workflow in [`variant-save-workflow.md`](variant-save-workflow.md), and application-workspace Gate 1 in [`application-workspaces.md`](application-workspaces.md) are implemented. Synthetic PDF compatibility covers reviewed Chromium-generated tagged/untagged and ReportLab-generated two-page documents, embedded-font and multi-column layouts, and fail-closed text-unavailable cases. The Git-history/tree/hash-bound token-optimization study is complete: its frozen before/after evidence includes Pi Skill discovery and matching-task full-Skill context and records a 15.98% aggregate workflow reduction with no workflow regression. Application-workspace assisted resume artifacts, deletion, repair/adoption/archive/sync, broader workspace files, and further PDF extraction expansion remain later separately approved phases.
4
4
 
5
- ## Current phase: managed agent tool and deterministic slash commands
5
+ ## Approved target: `/career` as a local Pi application
6
+
7
+ ### Application catalog filter (P3-49)
8
+
9
+ The shared Applications view supports bounded transient text and lifecycle filters in both TUI (`/` for text, `l` for All/Preparing/Applied/Interviewing/Closed, then clear with `k`) and RPC. Text matching is a deterministic, case-sensitive substring over the already-safe displayed company/role labels, lifecycle status, readiness text, and aggregate classification. Filters perform no Unicode normalization and never inspect paths, document bodies, hashes, raw errors, or invalid-child details; UUID row identity remains distinct when labels match. Filter state exists only in the current overlay instance, is clearable, and creates no config, workspace, session, or model/provider entry. Browsing, opening, filtering, and clearing do not attach, activate, call Career Core, submit messages, or expose Career Skill/tool metadata.
10
+
11
+ The application-centric roadmap treats `/career` as a user-invoked modal application inside Pi. It is not a chat prompt, model command, or full-screen replacement for Pi. Its execution model has three separate planes:
12
+
13
+ | Plane | User trigger | Execution boundary | Model/session effect |
14
+ |---|---|---|---|
15
+ | Overlay navigation | Open `/career`; browse, search, filter, open local detail, or review readiness | Local extension UI and bounded filesystem reads | No provider/model call, message submission, Career-specific model context, attachment, or session append |
16
+ | Deterministic work | Explicit Analyze or Match action | Career Core through the reviewed resolver, with existing compatibility, stdin, cancellation, and output bounds | No provider/model call or model-context activation; only separately approved persistence may append or write |
17
+ | Model assistance | Explicit Ask Pi/Regenerate/Suggest/Explain action followed by review and ordinary user submission | One application-scoped Pi assistance session using the bundled Skill and primary `career_run` tool | Career context and tokens begin only for this action; no package-initiated submission |
18
+
19
+ “Token-free overlay” means the first two planes cause no model turn and add no Career document, result, Skill content, or tool contract to a model request. The target also removes Career-specific Skill discovery metadata and tool schemas from ordinary Pi sessions that have not been explicitly activated for Career assistance. A local Core operation can consume CPU and may perform the already bounded exact-package acquisition before private stdin; it still consumes no model tokens. `PI_OFFLINE=1` disables that acquisition for offline testing/use but is not required for normal overlay operation.
20
+
21
+ ### Read, cache, and refresh contract
22
+
23
+ One overlay open or explicit refresh takes one bounded catalog snapshot. List views use only that projection and never read every document body. Exact document bytes and larger local details are loaded lazily only after the user opens the corresponding detail or starts an eligible action. Derived readiness is calculated locally from validated current metadata; it is never persisted or model-derived.
24
+
25
+ Library originals (Markdown, text, or extracted searchable PDF text) and attached application job descriptions, selected originals, and effective Resumes offer a separate **Preview document (local only)** action from their metadata detail. TUI uses `v`; RPC selects the named action after opening a row. Opening a row or a one-item list never reveals the body. Preview rescans or reloads the validated attached authority and checks the selected identity and text digest before display; unavailable, drifted, unsafe-control, or >12,000-byte text is rejected with a fixed payload-free message rather than truncated. The effective Resume is labeled original or tailored assisted, never presented as an original when assisted. Preview is read-only and transient: Back/Escape drops its text, no editor approval, Core call, provider send, attachment, session entry, or file write is performed. TUI displays six soft-wrapped lines per explicitly labeled page with ↑/↓ navigation instead of silently clipping long previews; RPC shows the full bounded exact text. No path or binary/PDF bytes are displayed. This is local UI authorization, not consent to model submission. Catalog, detail, and rendered-view caches are process-memory-only, bounded, and scoped to the current overlay instance. Closing the overlay drops UI/search/filter/cursor state. There is no persisted index, background watcher, polling loop, URL fetch, or speculative Core/model work. Returning from a dialog or completed mutation refreshes the affected bounded projection. Explicit Resume-library Rescan shows a local cancellable progress state and replaces the snapshot only after a complete scan; cancellation discards the candidate projection, so partial reads never masquerade as fresh complete state.
26
+
27
+ The Resume-library list and detail explicitly label every indexed record as `Original` or `Assisted variant`, show format, availability, current-session analysis state, and payload-free scan notices, and keep quarantined/unreadable entries non-authoritative. An available highlighted Original may run deterministic Analyze directly: its exact in-memory document/root/format/text-digest identity is revalidated after confirmation and again at Core submission, with no fallback chooser or alternate Resume. Drift, stale/capped scans, oversized input, assisted variants, and quarantined metadata fail closed. Root add/remove and rescan remain explicit local actions; removal changes config only after confirmation and never changes files beneath the root.
28
+
29
+ Before any mutation, Core invocation, attachment, or model handoff, the adapter revalidates the selected identity, root, referenced bytes, and action prerequisites under the owning workflow’s race rules. Drift invalidates the action and requires a fresh view; cached display data never becomes write, Core, or prompt authority.
30
+
31
+ ### Session and model-context boundary
32
+
33
+ Browsing never attaches an application. The approved #64 attachment stores only the exact bounded, path-free application/root identity pointer in a Pi custom entry after the separate session-persistence decision; it stores no document, result, prompt, or provider content and does not itself activate a Career Skill/tool or authorize provider submission. Workspace files remain the application authority.
34
+
35
+ An explicit assistance action revalidates the application and uses one company/role per assistance session so prior-company conversation content cannot leak into another application. The action may prepare a visible editor message and may establish a fresh application-scoped Pi session, but it must never call `sendMessage()`, `sendUserMessage()`, or an equivalent automatic submission path. Only the user’s later ordinary submission activates the provider boundary. Within that explicitly activated assistance session, the Career Skill and compact `career_run` contract remain stable rather than being toggled every turn, preserving prompt-cache reuse. The exact raw compatibility tools remain inactive unless the user explicitly requests raw/debug mode.
36
+
37
+ Restart, `/new`, branch, detach, unavailable-root, and identity-drift behavior must revalidate the bounded pointer and fail closed; no session is reconstructed from workspace files alone. Overlay route state and cached private bytes are never written to the Pi session. Session persistence, application attachment, assistance activation, provider submission, artifact mutation, and deletion are distinct approvals.
38
+
39
+ ### Ordered delivery and acceptance invariants
40
+
41
+ Application state uses one schema; former state `.v1`/`.v2` identifiers are unsupported, and append-only revision numbers remain only integrity/history controls. The Resume-library and persistent-Applications slices are implemented on #64's exact attachment, command-authority, and context-on-demand lifecycle. A valid attached application is the default `/career` detail; otherwise the deterministic persistent catalog opens. Detail shows lifecycle, all three readiness components, effective-Resume authority, current-session match state, and last-update metadata. Applied remains independent from readiness and requires an extra visible warning when the package is incomplete. Remaining user-visible work advances through job/effective-Resume, cover-letter, and integrated preparation slices before #59 validates the complete product.
42
+
43
+ Every overlay slice must prove with synthetic scenarios that:
44
+
45
+ 1. opening, closing, resizing, browsing, filtering, searching, and local detail navigation make no provider/model call, submit no message, append no session entry, and activate no Career-specific model context;
46
+ 2. list rendering uses one bounded metadata snapshot and does not read document bodies;
47
+ 3. local Analyze and Match remain explicit, cancellable Career Core operations with zero model calls/tokens;
48
+ 4. cached state is revalidated before mutation, Core use, attachment, or handoff, and observed drift fails closed;
49
+ 5. only an explicit assistance action may prepare Career model context, and preparation remains visibly reviewable without automatic submission;
50
+ 6. application attachment neither implies assistance activation nor provider or mutation consent;
51
+ 7. `career_run` remains the primary managed tool once assistance is active, while `career_core_discover`, `career_core_resume`, and `career_core_job` retain their exact compatibility names and stay inactive by default;
52
+ 8. branch/session replacement clears process-local handles and uses only the fresh Pi context;
53
+ 9. no persisted index, watcher, prompt/result cache, document duplication, telemetry, or background work is introduced; and
54
+ 10. benchmarks report ordinary model turns outside activated Career assistance sessions as zero Career-specific context tokens, separately from activated workflows, and preserve stable activated-session surfaces for prompt caching.
55
+
56
+ TUI overlay and RPC select/confirm dialogs render one Career view model. **Applications** and **Resumes** are its only peer top-level destinations. Setup belongs under Resumes; job description, Analyze, Match, Workspace, and Ask Pi are application or Resume context. The existing `/career-setup`, `/career-library`, `/career-application`, `/career-vacancy`, `/career-match`, `/career-analyze`, `/career-workbench`, and `/career-workspace` commands remain direct compatibility routes into that same hierarchy rather than tabs. A contextual route shows its full breadcrumb and Escape/Back returns to its owning destination; TUI Left/Right or Tab switches only the two destinations. RPC **Switch view** remains available but likewise lists only Applications and Resumes.
57
+
58
+ Opening, browsing, filtering, switching destinations, viewing help, and highlighting do not attach, activate assistance, bind a Resume, call Core or a provider, or submit a message. Attach, add/remove/rescan library roots, create application, selected-original binding, analyze/match, vacancy edit/clear, status update, detach, Ask Pi, and Gate 1 workspace management are explicit contextual actions on that same model. In TUI mode, a contextual action that needs a native Pi input, editor, selection, or confirmation temporarily dismisses the Career modal so the native dialog owns the foreground, then restores the same Career session with refreshed data; local preview and cancellable rescan remain inside the modal. Attached selected-original binding uses the existing exact workspace preview and separate confirmation, while Analyze and Match require that authoritative binding instead of falling back to another library Resume. Application detail and prerequisite/empty states show current state, a derived recommended next action, and safe alternatives without executing that recommendation. Footer hints show only current navigation and eligible actions; TUI help describes the hierarchy without performing work.
59
+
60
+ The centered TUI modal has explicit host margin, one complete rounded theme-colored Unicode frame, connected separators, and equal interior horizontal padding. All header, breadcrumb, destination, body, preview, and footer rows are wrapped or bounded against the inner content width so the complete ANSI-styled outer line stays within Pi's supplied width. Its terminal-derived row budget always retains header, destinations, footer, and bottom border while scrolling only the content region; long catalogs keep selection visible, and detail/help expose Up/Down scrolling. Widths or heights too small for the minimum complete padded frame show only bounded resize guidance and no private preview bytes. TUI list labels wrap instead of being clipped so warning/state wording remains available at narrow supported widths; selection also has a visible text marker independent of theme color. Rendering is recomputed at the supplied viewport, so resizing does not retain stale layout or theme-colored output.
61
+
62
+ The integrated application journey is presented as persisted package review rather than a second workflow engine. Applications detail classifies job description, selected Resume, cover letter, effective Resume authority, readiness, match evidence, and application classification; it exposes a derived contextual next action, while existing alternatives remain available in the view navigation and action list. The recommendation is informational only: create/attach, job-description editing, Original selection, Analyze/Match, workspace materialization/cover-letter authoring, and Applied status each retain their existing explicit confirmation and cancellation boundaries. Closing/reopening reconstructs the recommendation from the current validated workspace/catalog and explicit session attachment/activation; no overlay progress is authority.
63
+
64
+ ## Implemented current phase: managed agent tool and deterministic slash commands
6
65
 
7
66
  The normal active model surface is one compact `career_run` tool. The exact raw compatibility tools remain registered but inactive until `/career-tools raw` explicitly enables them:
8
67
 
@@ -12,18 +71,15 @@ The normal active model surface is one compact `career_run` tool. The exact raw
12
71
 
13
72
  It also registers:
14
73
 
15
- - `/career-setup` for library/privacy onboarding and a suggestion-only preferred variation directory—not external CLI installation
16
- - `/career-library` for explicitly configured searchable PDF, Markdown, and text resume roots, with actionable extraction notices
17
- - `/career-application` for session-scoped company/role identity and vacancy/result isolation
18
- - `/career-vacancy` for bounded vacancy input after session-persistence consent
19
- - `/career-match` for deterministic multi-resume matching and conservative ranking
20
- - `/career-analyze` for deterministic single-resume readiness detail
21
- - `/career-workbench` for a bounded, guided, visibly reviewable rebuild handoff to the user's normal Pi editor
74
+ - `/career` and `/career-setup`, `/career-library`, `/career-application`, `/career-vacancy`, `/career-match`, `/career-analyze`, `/career-workbench`, and `/career-workspace` to open one Career view model at different starting views; TUI overlay and RPC select/confirm dialogs are only renderers of that model
75
+ - `/career-setup status` and `/career-library status` for local configuration/library notices
76
+ - `/career-application status|clear` for attached detach or session-scoped application context
77
+ - `/career-vacancy clear` for the existing fail-closed vacancy clear, including print/JSON when unattached
22
78
  - `/career-review` for TUI-only, bounded inspection and explicit selection of current non-PDF retained variant changes
23
79
  - `/career-save` for user-only TUI/RPC exact preview, confirmation, and no-clobber local saving of one current Markdown/text materialization
24
80
  - `/career-tools` to switch between the managed-only and advanced raw model-tool surfaces
25
81
 
26
- `career_run`, the raw compatibility tools, `/career-vacancy`, `/career-match`, and `/career-analyze` invoke the compatible Career Core route selected by the external resolver on supported macOS/Linux systems. Package metadata rejects other systems, and direct local/Git extension initialization registers no command/tool and fails with `unsupported_platform` before route work or private stdin. Managed compatibility is validated before private input, and the reviewed exact package may be acquired only after local routes fail unless `PI_OFFLINE=1`. `career_run` validates Phase 8 operation/schema contracts internally, resolves current originals/vacancy through ephemeral handles, keeps complete results in bounded process memory, and exposes compact detail hydration without nested `input_json`. Setup/library scanning remains local. `/career-application` manages consented session state only. `/career-workbench` does not invoke Core or a provider/model itself: it prepares an ordinary editor message containing one original resume and, only for tailoring, the current vacancy. Guided modes cover complete score explanation, reviewed improvement suggestions, a question-led factual interview before reviewed replacements, direct reviewed exact replacements, and vacancy-specific variant review. The user must review and submit that message separately through Pi. `/career-review` also invokes neither Core nor a provider: it reads one current in-memory non-PDF variant review, requires warnings/discards acknowledgment and exact per-change inspection before inclusion, then prepares a later editor message containing only the unchanged review handle and selected canonical IDs.
82
+ `career_run` and the raw compatibility tools invoke the compatible Career Core route selected by the external resolver on supported macOS/Linux systems. The `/career*` view commands do not invoke Core while browsing. Package metadata rejects other systems, and direct local/Git extension initialization registers no command/tool and fails with `unsupported_platform` before route work or private stdin. Managed compatibility is validated before private input, and the reviewed exact package may be acquired only after local routes fail unless `PI_OFFLINE=1`. `career_run` validates Phase 8 operation/schema contracts internally, resolves current originals/vacancy through ephemeral handles (workspace sources when a persistent application is attached and activated), keeps complete results in bounded process memory, and exposes compact detail hydration without nested `input_json`. Setup/library scanning remains local. Opening or browsing a Career view never attaches, activates assistance, calls Core or a provider, or submits a message. Attach remains confirmation-gated, path-free, and assistance-inactive. `/career-review` also invokes neither Core nor a provider: it reads one current in-memory non-PDF variant review, requires warnings/discards acknowledgment and exact per-change inspection before inclusion, then prepares a later editor message containing only the unchanged review handle and selected canonical IDs.
27
83
 
28
84
  Binding boundaries:
29
85
 
@@ -47,8 +103,9 @@ Binding boundaries:
47
103
  - raw tool JSON remains authoritative; managed projections refer to complete authoritative in-memory results by handle, while prose hydrates only requested evidence and retained items
48
104
  - PDF workbench output is suggestion-only because extracted text cannot expose or preserve visual layout; Markdown/text prompts require existing structure and unchanged wording to remain intact
49
105
  - no full-result file export; `/career-save` persists only exact approved assisted document bytes and bounded marker/sidecar metadata
106
+ - `/career-workspace` is absent from model tools, calls no Core/runtime/provider/model/network/child process, appends no session entry, and persists only separately previewed Gate 1 config/marker/manifest/state/vacancy metadata under one strict disjoint private root
50
107
 
51
- The approved workflow specification fixes command behavior, persistence format, non-TUI behavior, bounded UI, and cancellation ownership. Print/JSON modes fail closed except for the pure `/career-vacancy clear` state action. Company/role isolation and future opt-in artifact persistence follow the separate [`application-workspaces.md`](application-workspaces.md) contract.
108
+ The approved workflow specification fixes command behavior, persistence format, non-TUI behavior, bounded UI, and cancellation ownership. Print/JSON modes fail closed except for the pure `/career-vacancy clear` state action. Company/role isolation and implemented Gate 1 application state persistence follow the separate [`application-workspaces.md`](application-workspaces.md) contract. Workspace-assisted artifacts and deletion remain unimplemented Gates 2 and 3.
52
109
 
53
110
  ## Assisted handoff and later materialization
54
111
 
@@ -0,0 +1,69 @@
1
+ # pi-career 0.4.0 release record
2
+
3
+ **Status: released and immutable.** `pi-career@0.4.0` is published as `latest` from commit `31d1a8068ddff727cd7bb27e7546965def51e574`; the annotated unsigned `v0.4.0` tag and asset-free GitHub Release target that same commit. The complete local candidate ladder passed on 2026-10-04, including fixture parity against the exact reviewed Career Core `v0.2.0` checkout, and same-SHA hosted evidence passed before publication. The publication incident and recovery are recorded below and in [`releasing.md`](releasing.md). This historical record is not authorization to move or recreate the tag, rerun publication, republish the immutable npm version, or alter its GitHub Release.
4
+
5
+ ## Version rationale and scope
6
+
7
+ The selected **0.4.0** version reflects the substantial additive, user-visible application-centric workflow: one shared Career overlay across TUI/RPC, persistent application catalog and attachment, workspace-backed current vacancy and selected-original authority, explicit lifecycle/revision handling, readiness presentation, and the separately approved user-authored cover-letter transaction. This is not a breaking change to the canonical application-state contract. It does not justify 1.0: boundaries and later workspace gates remain deliberately narrow.
8
+
9
+ The release scope is only the implemented application-centric experience recorded in the dated `CHANGELOG.md` 0.4.0 entry: one shared overlay and views; application create/catalog/attach; library-root add/rescan/remove; confirmation-gated analyze/match, vacancy edit, status update, and workspace management; workspace-backed vacancy/selected-original authority and lifecycle; derived readiness/next action; and user-authored cover-letter handling. Legacy identity-only migration remains exact-label, canonical-byte-previewed, separately confirmed, and no-clobber. Preserve the exact `career_run` primary managed tool, raw compatibility names, Core contract, local-first runtime boundary, consent/privacy/cancellation guarantees, and native-free package. Release claims must be checked against the final source rather than copied from this record.
10
+
11
+ ### State and migration distinctions
12
+
13
+ Application-state revisions use the single canonical schema identifier `pi.career.application_state`. They have **no schema-version migration or compatibility reader**: former `.v1`/`.v2` and other unsupported identifiers fail closed, are not adopted/repaired/rewritten, and do not expose a trusted prefix. This is distinct from the separately versioned user configuration contract. Ordinary setup/mutations preserve canonical config v1; only the explicit application-root configuration flow can migrate config v1 to v2, after exact preview and separate user confirmation. Never imply that application-state changes migrate config, or that config migration converts application-state files. See [single application-state contract](single-application-state.md) and [workspace design](application-workspaces.md).
14
+
15
+ ### Deferred / not part of 0.4.0
16
+
17
+ No inferred future scope: workspace resume artifacts and deletion, arbitrary files/browsing, adoption, repair, rebind, archive, synchronization, encryption/secure deletion, broad artifact formats, provider-response/result persistence, automated submission, model/provider behavior, telemetry, MCP, Windows, new native targets, runtime/Core upgrades, or application-state migration. Any later workspace gate requires its own review/authorization. The separate `/career-save` workflow remains distinct.
18
+
19
+ ## Support claims (exact, no extrapolation)
20
+
21
+ - Node.js: `>=22.19.0` per package engine; do not advertise an upper tested range or a different minimum.
22
+ - Pi APIs: the README's exact claim is “1.0.0-compatible package APIs.” Development dependency pins are exact 1.0.2; they do not prove a broader tested compatibility range. Do not claim “Pi 1.0+” or infer newer/older versions.
23
+ - Career runtime: exact `@revazi/career@0.2.0`, managed Core 0.2.0 contract; not a range.
24
+ - Native targets, delegated to that reviewed launcher: `darwin-arm64`, `darwin-x64`, `linux-x64-gnu`, `linux-arm64-gnu`, `linux-x64-musl`, `linux-arm64-musl`. GNU Linux requires glibc 2.35+. No Windows or other target claim.
25
+
26
+ ## Privacy, retention, and screenshots
27
+
28
+ All examples, UI captures, and render checks use synthetic labels/documents, synthetic paths, and disposable sessions/workspaces only. Never use real user records, credentials, provider responses, or session content. A screenshot/render review may cover compact/wide TUI layout, overlay navigation/empty state, and representative RPC dialogs; check wrapping, clipping, visible consent/confirmation, and absence of unintended private detail. Do not inspect or modify protected PNGs. Any new image must be generated from synthetic fixtures, separately reviewed for metadata/content, and added to the exact package allowlist only if intentionally packaged; no screenshot is required for the release.
29
+
30
+ Local documents and Pi sessions, RPC clients, editor history, backups/snapshots/sync, provider systems, and npm cache are distinct retention surfaces. Exact runtime acquisition receives no private document stdin, but ordinary npm cache or `_npx` residue may remain; this is not secure erasure. Do not promise cache cleansing or secure deletion. Existing privacy and persistence descriptions remain authoritative.
31
+
32
+ ## Evidence matrix — completed release
33
+
34
+ The 2026-10-04 local results cover the bytes later frozen at `31d1a8068ddff727cd7bb27e7546965def51e574`. Hosted and registry evidence below is tied to that same immutable commit.
35
+
36
+ | Gate / evidence | Historical outcome |
37
+ | --- | --- |
38
+ | Release identity | Package, root lockfile entries, Skill metadata, package assertions, release helpers, README coordinate, and dated changelog identify 0.4.0; annotated unsigned tag `v0.4.0` and the asset-free GitHub Release target the frozen commit. |
39
+ | Build / dist reproducibility | Passed immediately after `npm run build` against the tracked bundles and again in the release gates. |
40
+ | Token and complete adapter checks | `bench:tokens`, `bench:tokens:compare`, and `check` passed locally; same-SHA Adapter run [`37191508057`](https://github.com/revazi/pi-career/actions/runs/37191508057) passed. |
41
+ | Exact Career package runtime integration | Passed locally with exact `@revazi/career@0.2.0`, including synthetic managed discovery and representative resume/job operations; same-SHA six-target run [`37191625998`](https://github.com/revazi/pi-career/actions/runs/37191625998) passed. |
42
+ | Production and full audits | Both passed with zero vulnerabilities at the explicit low threshold under exact Pi 1.0.2 development pins. No acceptance baseline was used. |
43
+ | Package/publication | `check:publish` passed and the native-free package was published through OIDC in run [`37191969844`](https://github.com/revazi/pi-career/actions/runs/37191969844). Registry integrity is `sha512-ks5xCnt2sDKCTzjvUuRQCJJSGaiHvt1lmwJNT6hhJLIV2MCmCrOUOG2dLW9uhdyGjHXR7Eu4SRlBXSNAVDtWpA==`; shasum is `460b9d69b42bc572bf966498a34c8818c3f26a6a`. |
44
+ | Fixture-backed compatibility | Passed, not skipped, against reviewed Career Core commit `536690632884c17336cc3c108f1bba0f254b862b` / `v0.2.0`; the fixture checkout remained read-only and local. |
45
+ | Offline and isolated package acceptance | Pre-release offline Pi load and isolated install/remove passed. After publication, an isolated agent-directory test passed exact install/list/load, acquisition, synthetic resume and job operations, offline failure, and removal. |
46
+ | Authoritative registry state | `pi-career@0.4.0` is immutable and `latest`; exact metadata, tarball bytes, `gitHead`, trusted publisher, provenance, and dist-tag were independently verified after propagation settled. |
47
+ | Publication incident and recovery | Run `37191969844` published successfully but failed during bounded post-publish registry verification. No rerun or republish occurred; the checked-in GitHub Release creator completed asset-free bookkeeping only after authoritative verification. |
48
+
49
+ The complete pre-release local ladder passed: `npm ci`; `npm run build` plus immediate candidate-relative dist comparison; `npm run bench:tokens`; `npm run bench:tokens:compare`; `npm run check`; `npm run test:runtime-resolution`; `npm run test:career-package`; `npm run audit:production`; `npm run audit:full`; `npm run check:publish`; `PI_OFFLINE=1 npm run test:pi-smoke`; `PI_OFFLINE=1 npm run test:install`; fixture-backed `npm run test:compat`; `npm ls --omit=dev --depth=0`; `git diff --check`. The exact Pi development pins remain 1.0.2, and the resolved vulnerable `brace-expansion@5.0.9` selection was absent. These are historical candidate and release results, not authorization for a new publication action.
50
+
51
+ ## Historical publication path and immutable-release safeguards
52
+
53
+ The release used the sole publication path, [.github/workflows/release.yml](../.github/workflows/release.yml), triggered by the reviewed annotated unsigned `v0.4.0` tag:
54
+
55
+ - GitHub Actions trusted publisher was exactly `revazi/pi-career`, workflow `release.yml`, environment `npm`, with the protected `npm` environment enabled.
56
+ - The workflow granted `id-token: write` only to the publication job and used no long-lived npm token, `NPM_TOKEN`, `NODE_AUTH_TOKEN`, OTP, manual token publishing, or alternate workflow/path.
57
+ - Pinned checkout/setup-node actions, Node 22.19.0, exact npm 11.6.2, lifecycle-disabled dependency installation/publication, and provenance settings matched the reviewed workflow.
58
+ - Tag/version/changelog/lockfile/full SHA/annotated unsigned tag checks, same-SHA hosted gates, complete audits/package gates, and clean-tree checks passed before publication.
59
+ - The authoritative registry represented the trusted publisher's OIDC configuration as bare UUID `59e29379-4ad7-4ac5-8484-68bba66677fe`; the publisher name, email, and `github` provider ID remained exact.
60
+
61
+ ### Registry-first and ambiguous-outcome rule
62
+
63
+ The authoritative registry reported `pi-career@0.4.0` absent before the one authorized publication. When the post-publication workflow result became ambiguous, maintainers did **not** rerun the workflow, republish, move/replace the tag, or attempt overwrite. They first inspected exact version metadata, dist-tag, tarball integrity/shasum, provenance/publisher identity, and `gitHead`. Because the exact package was present, recovery was limited to verification and GitHub Release bookkeeping with the existing checked-in helper. This rule remains mandatory: preserve evidence and stop if registry state is indeterminate; never treat a failed post-publication check as permission for an automatic retry or alternate publication channel.
64
+
65
+ ## Recovery and post-release verification
66
+
67
+ `pi-career@0.4.0` cannot be overwritten or “rolled back” by republishing, and its tag must not move. Run `37191969844` exceeded the former registry propagation bound after successful publication; the now-authoritative registry metadata also used a bare UUID where the verifier expected the historical `oidc:` prefix. The package's exact identity and bytes were independently verified, so no rerun or republish occurred. The checked-in `scripts/create-github-release.mjs` then created the asset-free GitHub Release against the existing tag.
68
+
69
+ Independent verification proved npm integrity `sha512-ks5xCnt2sDKCTzjvUuRQCJJSGaiHvt1lmwJNT6hhJLIV2MCmCrOUOG2dLW9uhdyGjHXR7Eu4SRlBXSNAVDtWpA==`, shasum `460b9d69b42bc572bf966498a34c8818c3f26a6a`, exact `gitHead`, provenance and trusted publisher, `latest` dist-tag, tag/Release target, and absence of native or custom Release assets. In an isolated Pi agent directory, exact `npm:pi-career@0.4.0` install/list/load, runtime acquisition with synthetic resume and job operations, offline failure, and removal all passed. No production-wire claim is inferred from synthetic operation fixtures beyond acceptance of this exact published package.
package/docs/releasing.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Release process
2
2
 
3
- This document defines the bounded trusted-publishing process for the next explicitly authorized pi-career release and records the historical `v0.1.0` and `v0.2.0` outcomes. In the instructions below, `<version>` is the exact package version without `v`, `<tag>` is `v<version>`, and `<sha>` is the full frozen candidate commit.
3
+ This document defines the bounded trusted-publishing process and records the historical `v0.1.0`, `v0.2.0`, `v0.3.0`, and `v0.4.0` outcomes. Candidate metadata and the dated changelog must be finalized before the release SHA is frozen; tracked files do not embed that self-referential SHA. Publication and tag creation always require the separate explicit authorization described below. In the instructions below, `<version>` is the exact package version without `v`, `<tag>` is `v<version>`, and `<sha>` is the full frozen candidate commit.
4
4
 
5
5
  ## Release boundary
6
6
 
@@ -54,6 +54,47 @@ In run `31353182855`, every gate and the OIDC `npm publish` step succeeded. The
54
54
 
55
55
  **Never rerun or republish after an ambiguous publish response.** Query authoritative registry state first. A post-publication recovery may finish verification and release-channel bookkeeping only; it must not create an alternate publication path, overwrite an immutable npm version, or move the published tag.
56
56
 
57
+ ## Historical `v0.3.0` outcome
58
+
59
+ Release execution completed on 2026-08-14:
60
+
61
+ - npm: [`pi-career@0.3.0`](https://www.npmjs.com/package/pi-career/v/0.3.0)
62
+ - published commit: `2c0da9ff623b50cc02a7b5bccd3cb047596d947e`
63
+ - annotated unsigned tag and asset-free GitHub Release: [`v0.3.0`](https://github.com/revazi/pi-career/releases/tag/v0.3.0)
64
+ - npm integrity: `sha512-u/odRK/KMYXhIt/lvGm93RFmQIwBQZV0qbAf1vs/GsNH8Fx/X2f+p+F1iyUYtMi5RH9++SkdhEN8CR2XBScyBw==`
65
+ - npm shasum: `3ad37db78cb76330838fbb3efe722c1cff4d8d00`
66
+ - same-SHA main Adapter checks: [`31790996492`](https://github.com/revazi/pi-career/actions/runs/31790996492)
67
+ - same-SHA six-target compatibility run: [`31791011739`](https://github.com/revazi/pi-career/actions/runs/31791011739)
68
+ - OIDC publication, authoritative registry verification, and GitHub Release run: [`31791158472`](https://github.com/revazi/pi-career/actions/runs/31791158472)
69
+ - npm publisher identity: GitHub Actions trusted publisher for `revazi/pi-career`, workflow `release.yml`, environment `npm`
70
+ - SLSA provenance subject and resolved Git dependency: exact `pi-career@0.3.0` tarball and commit above
71
+ - exact public Pi install/list/runtime acquisition with synthetic operations/offline failure/remove acceptance: passed
72
+ - custom GitHub Release assets: none
73
+
74
+ The published package is native-free, supports the six reviewed macOS/Linux targets through exact external `@revazi/career@0.2.0`, and validates its exact ordered six-package v2 launcher manifest. Production and complete development/host-Pi audits were both clean at the explicit low threshold before publication.
75
+
76
+ ## Historical `v0.4.0` outcome
77
+
78
+ Release execution completed from the frozen 2026-10-04 candidate:
79
+
80
+ - npm: [`pi-career@0.4.0`](https://www.npmjs.com/package/pi-career/v/0.4.0), promoted as `latest`
81
+ - published commit: `31d1a8068ddff727cd7bb27e7546965def51e574`
82
+ - annotated unsigned tag and asset-free GitHub Release: [`v0.4.0`](https://github.com/revazi/pi-career/releases/tag/v0.4.0), both targeting that commit
83
+ - npm integrity: `sha512-ks5xCnt2sDKCTzjvUuRQCJJSGaiHvt1lmwJNT6hhJLIV2MCmCrOUOG2dLW9uhdyGjHXR7Eu4SRlBXSNAVDtWpA==`
84
+ - npm shasum: `460b9d69b42bc572bf966498a34c8818c3f26a6a`
85
+ - same-SHA main Adapter checks: [`37191508057`](https://github.com/revazi/pi-career/actions/runs/37191508057)
86
+ - same-SHA six-target compatibility run: [`37191625998`](https://github.com/revazi/pi-career/actions/runs/37191625998)
87
+ - OIDC publication and post-publication verification run: [`37191969844`](https://github.com/revazi/pi-career/actions/runs/37191969844)
88
+ - npm publisher identity: exact GitHub Actions trusted publisher; registry `oidcConfigId` `59e29379-4ad7-4ac5-8484-68bba66677fe`
89
+ - exact published-package Pi install/list/load, runtime acquisition with synthetic resume and job operations, offline failure, and removal in an isolated agent directory: passed
90
+ - custom GitHub Release assets: none
91
+
92
+ Run `37191969844` passed every pre-publication gate and published the immutable package successfully through OIDC. Its post-publication job then failed closed before GitHub Release creation: canonical registry propagation exceeded the verifier's former 36-attempt, five-second interval, and the settled registry metadata represented `trustedPublisher.oidcConfigId` as a bare UUID rather than the historical `oidc:<UUID>` spelling. The UUID value and exact GitHub publisher name, email, and provider ID matched the reviewed identity. This was a release-tooling compatibility incident, not evidence that publication failed.
93
+
94
+ No workflow rerun, tag movement, or npm republish occurred. After authoritative registry state proved the exact metadata, `gitHead`, tarball integrity/shasum, trusted publisher, provenance, and `latest` dist-tag, the existing checked-in `scripts/create-github-release.mjs` completed the asset-free GitHub Release bookkeeping. Independent isolated acceptance then exercised the exact published package as recorded above. `v0.4.0` and `pi-career@0.4.0` are immutable; this hardening must not alter or recreate them.
95
+
96
+ Future registry-resource polling uses exactly 48 attempts at five-second intervals: at most 47 scheduled sleeps, or 235 seconds of propagation delay, with each request retaining its separate 30-second timeout. Only `404`, `5xx`, and request failures are retried within that finite bound. Other HTTP statuses fail immediately; authoritative metadata, provenance, integrity, publisher, and `gitHead` mismatches fail closed, and an indeterminate final state never authorizes an automatic publication retry.
97
+
57
98
  ## Release gates
58
99
 
59
100
  A skipped, unknown, stale, or merely planned result is not a pass.
@@ -0,0 +1,110 @@
1
+ # Single application-state contract — issue #140
2
+
3
+ ## Status and scope
4
+
5
+ This contract replaces application-state schema versioning with one exact pi-career-owned schema:
6
+
7
+ ```text
8
+ pi.career.application_state
9
+ ```
10
+
11
+ Issue #140 approved this contract. Issue #141 implements production, fixture, generated-bundle, and documentation convergence.
12
+
13
+ There is no application-state schema migration or compatibility path. Files whose `schema_version` is `pi.career.application_state.v1`, `pi.career.application_state.v2`, or any other value are unsupported and fail closed. They are never rewritten, adopted, interpreted as a compatible prefix, or exposed as current state.
14
+
15
+ Append-only numbered revisions are retained. Revision numbers and parent hashes protect immutable history, concurrency, crash settlement, and no-clobber publication; they are not schema versions.
16
+
17
+ ## Canonical schema
18
+
19
+ Every state revision is canonical two-space JSON plus one LF with these exact ordered keys:
20
+
21
+ ```json
22
+ {
23
+ "schema_version": "pi.career.application_state",
24
+ "kind": "application_state_revision",
25
+ "application_id": "00000000-0000-4000-8000-000000000001",
26
+ "sequence": 1,
27
+ "parent_sha256": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
28
+ "status": "preparing",
29
+ "vacancy": null,
30
+ "selected_original": null,
31
+ "resume_artifact": null,
32
+ "cover_letter_artifact": null,
33
+ "updated_at": "2026-08-12T00:00:01.000Z"
34
+ }
35
+ ```
36
+
37
+ The field meanings and bounds remain:
38
+
39
+ - `application_id`: canonical lowercase application UUID bound to the immutable manifest.
40
+ - `sequence`: integer 1 through 64 matching the six-digit state filename.
41
+ - `parent_sha256`: SHA-256 of the exact manifest bytes for sequence 1, otherwise of the immediately preceding exact state bytes.
42
+ - `status`: `preparing`, `applied`, `interviewing`, or `closed`.
43
+ - `vacancy`: `null` or the existing exact ordered vacancy reference.
44
+ - `selected_original`: `null` or the existing exact ordered original Resume binding.
45
+ - `resume_artifact`: `null` or the existing exact ordered assisted artifact and sidecar reference.
46
+ - `cover_letter_artifact`: `null` or the exact ordered reference below.
47
+ - `updated_at`: canonical UTC timestamp with milliseconds, strictly increasing across revisions.
48
+
49
+ A non-null cover-letter reference has exactly these ordered keys:
50
+
51
+ ```json
52
+ {
53
+ "relative_path": "cover-letter.md",
54
+ "artifact_sha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
55
+ "utf8_bytes": 42,
56
+ "format": "markdown",
57
+ "authority": "user_authored",
58
+ "job_description_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
59
+ "effective_resume_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
60
+ }
61
+ ```
62
+
63
+ Issue #57 separately authorizes a narrowly scoped user-authored writer using this exact reference shape. It does not authorize rebind, artifact deletion/adoption, or model-assisted content. The transaction, byte bound, authority, preview, confirmation, and immutable-history rules are specified in [`cover-letter-contract.md`](cover-letter-contract.md).
64
+
65
+ ## Complete-chain rules
66
+
67
+ A trusted chain contains only `pi.career.application_state` revisions and must satisfy all existing safety rules:
68
+
69
+ 1. State files begin at `.pi-career-state-000001.json`, are contiguous, match embedded sequence values, and never exceed 64 revisions.
70
+ 2. Sequence 1 hashes the immutable manifest; each later revision hashes the exact previous revision.
71
+ 3. Every revision binds the same application UUID and has a strictly later canonical timestamp.
72
+ 4. Every referenced package-owned file retains exact containment, ownership, mode, link-count, size, and hash validation.
73
+ 5. Gaps, forks, duplicate state-shaped names, malformed bytes, unsupported schema identifiers, historical managed-reference drift, races, and exceeded bounds reject the complete chain. No last-known-good prefix becomes current.
74
+ 6. Reads never mutate, migrate, repair, compact, adopt, or delete state.
75
+
76
+ New applications and every approved state mutation write only the one canonical schema. There is no transition revision, upgrade, downgrade, dual reader, or mixed-schema chain.
77
+
78
+ ## Readiness and authority
79
+
80
+ The existing pure readiness and effective-Resume rules operate on a fully validated single-schema head. Readiness remains derived rather than persisted or manually toggled. Lifecycle status and match results do not override component validity.
81
+
82
+ This simplification changes no authority or consent boundary:
83
+
84
+ - original Resumes remain immutable and external to application workspaces;
85
+ - workspace files remain authoritative for attached application state;
86
+ - Career Core remains authoritative for supported career-domain operations and contracts;
87
+ - no read, migration rejection, or readiness derivation invokes Core, a provider/model, network, telemetry, or session append;
88
+ - every mutation still requires exact preview, unchanged return, separate confirmation, fresh under-lock validation, no-clobber publication, state commit last, and payload-free errors;
89
+ - no private body, path, UUID, hash, environment value, raw error, Core result, prompt, or provider content is logged or exposed at the adapter boundary.
90
+
91
+ ## Acceptance scenarios for #141
92
+
93
+ | ID | Given | When | Then |
94
+ |---|---|---|---|
95
+ | S1-01 | Canonical single-schema sequence 1 | Read application | Accept exact state without mutation |
96
+ | S1-02 | Multiple contiguous single-schema revisions | Read application | Select the exact highest complete head |
97
+ | S1-03 | A former `.v1` or `.v2` identifier anywhere in the chain | Discover or read | Classify unsupported; trust no prefix and mutate nothing |
98
+ | S1-04 | Any other unsupported canonical schema identifier | Discover or read | Classify unsupported with a payload-free result |
99
+ | S1-05 | Gap, fork, duplicate name, bad parent, or malformed state | Discover or read | Fail closed under the existing drift classification |
100
+ | S1-06 | New application | Commit approved creation | Write sequence 1 using only `pi.career.application_state` |
101
+ | S1-07 | Approved status, vacancy, or selected-original mutation | Commit | Append one canonical single-schema revision |
102
+ | S1-08 | Nullable or valid non-null cover-letter reference | Parse and derive | Preserve the exact shape and existing readiness rules without authorizing a writer |
103
+ | S1-09 | Concurrent same-next-revision plans | Commit | One no-clobber winner; no fork, retry name, or overwrite |
104
+ | S1-10 | Capacity, byte, metadata, or post-preview race boundary | Plan or commit | Preserve existing before-preview and under-lock rejection |
105
+ | S1-11 | Unsupported former-schema application | Open overlay or restore attachment | Do not expose as valid/current, attach, migrate, or append |
106
+ | S1-12 | Any read or rejected mutation above | Observe side effects | No Core/provider/network/session/logging or unauthorized file effect |
107
+
108
+ ## Explicit exclusions
109
+
110
+ This contract does not authorize cover-letter persistence, deletion, archive, synchronization, repair, unknown-file adoption, provider behavior, a package-version change, publication, or release. It does not change config, marker, identity, attachment, activation, variant-sidecar, Career Core, or managed-tool schema identifiers.
@@ -4,7 +4,7 @@
4
4
 
5
5
  This document defines the implemented package-owned local save workflow for one successfully materialized, non-PDF assisted resume variant. The design was reviewed before implementation; implementation does not authorize publication, release, full-result export, or application-workspace persistence.
6
6
 
7
- The design is intentionally narrower than the future application workspace in [`application-workspaces.md`](application-workspaces.md). It saves only one materialized Markdown or text resume plus integrity metadata under the selected original's configured library root. It does not create `application.json`, persist a vacancy, save review input or Core JSON, generate a cover letter, or establish an application workspace root.
7
+ The design is intentionally narrower than the separate application workspace in [`application-workspaces.md`](application-workspaces.md); Gate 1 state/vacancy persistence is implemented, while workspace-assisted artifacts remain a later gate. It saves only one materialized Markdown or text resume plus integrity metadata under the selected original's configured library root. It does not create `application.json`, persist a vacancy, save review input or Core JSON, generate a cover letter, or establish an application workspace root.
8
8
 
9
9
  ## Goals
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-career",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "private": false,
5
5
  "description": "Pi tools, slash commands, and Agent Skill for deterministic Career Core workflows",
6
6
  "license": "MIT OR Apache-2.0",
@@ -44,7 +44,7 @@
44
44
  "test": "npm run test:process && npm run test:runtime && npm run test:workflow && npm run test:audit",
45
45
  "test:process": "node --import tsx --test tests/process/process.test.mjs",
46
46
  "test:runtime": "node --import tsx --test tests/runtime/runtime.test.mjs",
47
- "test:workflow": "node --import tsx --test tests/workflow/*.test.mjs",
47
+ "test:workflow": "node --import tsx --test --test-concurrency=1 tests/workflow/*.test.mjs",
48
48
  "test:audit": "node --test tests/audit/*.test.mjs",
49
49
  "test:runtime-resolution": "node --import tsx --test tests/runtime/runtime.test.mjs",
50
50
  "test:career-package": "node scripts/test-career-package.mjs",
@@ -71,16 +71,16 @@
71
71
  "typebox": "*"
72
72
  },
73
73
  "devDependencies": {
74
- "@earendil-works/pi-ai": "0.84.0",
75
- "@earendil-works/pi-coding-agent": "0.84.0",
76
- "@earendil-works/pi-tui": "0.84.0",
77
- "@types/node": "24.12.4",
78
- "esbuild": "0.28.1",
74
+ "@earendil-works/pi-ai": "1.0.2",
75
+ "@earendil-works/pi-coding-agent": "1.0.2",
76
+ "@earendil-works/pi-tui": "1.0.2",
77
+ "@types/node": "24.19.0",
78
+ "esbuild": "0.28.2",
79
79
  "js-tiktoken": "1.0.21",
80
- "tsx": "4.23.5",
81
- "typebox": "1.3.7",
80
+ "tsx": "4.23.13",
81
+ "typebox": "1.3.34",
82
82
  "typescript": "5.9.3",
83
- "unpdf": "1.8.0"
83
+ "unpdf": "1.8.1"
84
84
  },
85
85
  "publishConfig": {
86
86
  "access": "public",
@@ -89,9 +89,6 @@
89
89
  "pi": {
90
90
  "extensions": [
91
91
  "./dist/index.js"
92
- ],
93
- "skills": [
94
- "./skills/career-core"
95
92
  ]
96
93
  }
97
94
  }
@@ -5,7 +5,7 @@ license: MIT OR Apache-2.0
5
5
  compatibility: Requires Pi with pi-career on ARM64/x64 macOS or GNU/musl Linux and a compatible Career Core route. Windows is unsupported.
6
6
  metadata:
7
7
  author: revazi
8
- version: "0.3.0"
8
+ version: "0.4.1"
9
9
  ---
10
10
 
11
11
  # Career Core through pi-career