trackly-cli 0.20.0 → 0.20.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.
package/README.md CHANGED
@@ -121,7 +121,7 @@ trackly agent setup --client codex # or claude / both
121
121
  trackly agent doctor
122
122
  ```
123
123
 
124
- For an existing MCP configuration or a Cloud harness, use `trackly agent setup --client both --skills-only`. This installs the same checksummed skill for both native clients without invoking their MCP commands or changing authentication. CLI 0.20.0 carries universal skill 4.9.0; its policy revision is the same numeric version, superseding the personal revisions. The policy accepts a documented `markHandoff()` guarantee with awaited calls, exact current tab checks, and revalidation on later turns. These observations are never reported as returned persistence receipts. Browser capabilities and manual Submit remain separate requirements; installation does not make a Linux browser supported. The separately installed `trackly:trackly-apply` plugin is updated through its plugin manager; plugin 1.1.0 carries the same browser and profile lookup policies. This setup command does not patch plugin caches.
124
+ For an existing MCP configuration or a Cloud harness, use `trackly agent setup --client both --skills-only`. This installs the same checksummed skill for both native clients without invoking their MCP commands or changing authentication. CLI 0.20.1 carries universal skill 4.9.1; its policy revision is the same numeric version, superseding the personal revisions. The policy accepts a documented `markHandoff()` guarantee with awaited calls, exact current tab checks, and revalidation on later turns. These observations are never reported as returned persistence receipts. Browser capabilities and manual Submit remain separate requirements; installation does not make a Linux browser supported. The separately installed `trackly:trackly-apply` plugin is updated through its plugin manager; plugin 1.1.1 carries the same browser and profile lookup policies. This setup command does not patch plugin caches.
125
125
 
126
126
  The skill uses the profile and default resume in your Trackly account, asks only missing questions, fills user-approved saved jobs, and always stops before Submit. “Fill the next N” continues through the original recent-first Check Later snapshot until N unauthenticated forms are durably ready for your manual review; authentication walls and exclusions are reported separately and do not consume the target. An explicit “inspect the next N records” request still uses one fixed immutable batch. Support is fetched from Trackly at the start of every run: Greenhouse is full, Ashby and Lever are best effort, and 27 additional named ATS/provider classes use constrained guided mode. Employer-hosted unknown forms run only when Trackly binds them to a verified company domain. LinkedIn-hosted forms and unverified origins remain manual-only; a separately stored external application URL is evaluated under its own ATS and origin policy.
127
127
 
package/lib/agent.js CHANGED
@@ -8,7 +8,7 @@ const { spawnSync } = require('node:child_process');
8
8
  const { apiRequest, downloadFile, getConfigPaths, hasAuth, maintenanceOutput } = require('./client');
9
9
  const { version: PACKAGE_VERSION } = require('../package.json');
10
10
  const { contractVersion: MCP_CONTRACT_VERSION } = require('../contracts/trackly-apply-tools.json');
11
- const SKILL_VERSION = '4.9.0';
11
+ const SKILL_VERSION = '4.9.1';
12
12
  const SKILL_POLICY_REVISION = SKILL_VERSION;
13
13
  const CLI_USER_AGENT = `trackly-cli/${PACKAGE_VERSION}`;
14
14
  const MCP_USER_AGENT = `trackly-mcp/${PACKAGE_VERSION}`;
@@ -791,7 +791,7 @@ const startApplyRunSchema = z.object({
791
791
  }
792
792
  });
793
793
 
794
- const APPLY_RELIABILITY_PROMPT = 'Protocol 3.7 / skill 4.9.0 reliability gate: recover active work first. Consume the exact proposedWave and frozen accessKnowledge receipts before opening any browser. Rank OPEN ahead of neutral VARIES/UNKNOWN, then fresh ACCOUNT WALL; never auto-select an active user deferment. Historical OPEN never authorizes fill_form; freshLiveProbeRequired remains true. When nextAction is access_review, including ordinary OPEN or neutral proposals, display the exact accessProposal and accessProposal.approvalHash. If the proposal has nonempty members, obtain explicit approval for those exact ordered jobIds and call the hash-bound approval continuation. If the proposal has zero members because all remaining candidates are deferred or exact recovery is blocked by a user deferment, surface the deferred count and stable deferment IDs, offer clear-deferment only for explicitly returned IDs, stop, or expiry, and never send an empty approval. List or create deferments only at job, company, or provider scope through the jobId-bound tools; provider scope applies across companies until explicitly cleared. Do not open a browser or report the queue exhausted. Retain the latest explicit target as hard, prove genuine applicant fields before counting access, obtain approval for the exact accessible jobs before form mutation, fill all deterministic fields before one true-gap question packet, and validate each value-free phase checkpoint. Every checkpoint action must use its canonical continuationAllowed value; review/manual_submit, captcha/at_submit, trust/origin_mismatch, and observability/unverifiable_state require false. Fail closed on a rejected checkpoint. After full local context loss, list recoverable executions, show only stable job identity, obtain explicit confirmation of the exact candidate set, and call exact-member recovery without substitutions. An active personal deferment blocks exact recovery until cleared. Treat recovered tab presence, form state, and mutation authority as three separate facts; reacquire a fresh browser binding and inspection epoch before mutation. Before resolving broad submission statements, list active review handoffs for the execution; use only an explicit receipt or the sole returned active receipt, classify every member as detected, user_confirmed, unresolved, or contradictory, and claim that exact handoff before writing outcomes. Use provider-specific positive success evidence; an unchanged URL or title is never negative evidence. Validate an exact expected browser keep set locally before finalization. For resume uploads, negotiate the browser surface capabilities, identify the semantic control, arm the chooser before clicking, attach the immediately verified file, prove the user-facing filename committed, and recheck parser-modified fields. Use compact snapshots and server-provided mutability. Preserve user-edited and unknown non-empty fields. Never reopen parked work without explicit user resumption. Never click Submit.';
794
+ const APPLY_RELIABILITY_PROMPT = 'Protocol 3.7 / skill 4.9.1 reliability gate: recover active work first. Consume the exact proposedWave and frozen accessKnowledge receipts before opening any browser. Rank OPEN ahead of neutral VARIES/UNKNOWN, then fresh ACCOUNT WALL; never auto-select an active user deferment. Historical OPEN never authorizes fill_form; freshLiveProbeRequired remains true. When nextAction is access_review, including ordinary OPEN or neutral proposals, display the exact accessProposal and accessProposal.approvalHash. If the proposal has nonempty members, obtain explicit approval for those exact ordered jobIds and call the hash-bound approval continuation. If the proposal has zero members because all remaining candidates are deferred or exact recovery is blocked by a user deferment, surface the deferred count and stable deferment IDs, offer clear-deferment only for explicitly returned IDs, stop, or expiry, and never send an empty approval. List or create deferments only at job, company, or provider scope through the jobId-bound tools; provider scope applies across companies until explicitly cleared. Do not open a browser or report the queue exhausted. Retain the latest explicit target as hard, prove genuine applicant fields before counting access, obtain approval for the exact accessible jobs before form mutation, fill all deterministic fields before one true-gap question packet, and validate each value-free phase checkpoint. Every checkpoint action must use its canonical continuationAllowed value; review/manual_submit, captcha/at_submit, trust/origin_mismatch, and observability/unverifiable_state require false. Fail closed on a rejected checkpoint. After full local context loss, list recoverable executions, show only stable job identity, obtain explicit confirmation of the exact candidate set, and call exact-member recovery without substitutions. An active personal deferment blocks exact recovery until cleared. Treat recovered tab presence, form state, and mutation authority as three separate facts; reacquire a fresh browser binding and inspection epoch before mutation. Before resolving broad submission statements, list active review handoffs for the execution; use only an explicit receipt or the sole returned active receipt, classify every member as detected, user_confirmed, unresolved, or contradictory, and claim that exact handoff before writing outcomes. Use provider-specific positive success evidence; an unchanged URL or title is never negative evidence. Validate an exact expected browser keep set locally before finalization. For resume uploads, negotiate the browser surface capabilities, identify the semantic control, arm the chooser before clicking, attach the immediately verified file, prove the user-facing filename committed, and recheck parser-modified fields. Use compact snapshots and server-provided mutability. Preserve user-edited and unknown non-empty fields. Never reopen parked work without explicit user resumption. Never click Submit.';
795
795
 
796
796
  function registerApplyTools(
797
797
  server,
@@ -1973,7 +1973,7 @@ function registerApplyTools(
1973
1973
  content: { type: 'text', text: APPLY_RELIABILITY_PROMPT },
1974
1974
  }, {
1975
1975
  role: 'user',
1976
- content: { type: 'text', text: 'Before generating questions or filling controls, run the skill 4.9.0 deterministic answer resolver and profile lookup gate. Request the current contextual projection for every visible canonical key; compact omissions are not unknown answers. Commit compatible known answers before questions and run scripts/validate-profile-lookup.js on value-free accounting. Redacted or unavailable lookups are access problems, not missing facts; optional unknown demographics may remain blank; live consent stays separate. Classify every visible answer as exact_profile, safe_derivation, supported_draft, missing_fact, live_consent, or forbidden_inference; validate the control type; fill only the first three; and ask only currently visible unresolved needs. Treat the current profile revision as reusable authority, never transcript, screenshot, parser, autocomplete, or cached values. Accessible-first is a hard scheduler invariant: park known authentication, account-creation, OTP, and pre-form-CAPTCHA work without starting a draft while an accessible candidate remains. Curated OPEN and recent accessibility never change allowedOperations to fill_form.' },
1976
+ content: { type: 'text', text: 'Before generating questions or filling controls, run the skill 4.9.1 deterministic answer resolver and profile lookup gate. Request the current contextual projection for every visible canonical key; compact omissions are not unknown answers. Commit compatible known answers before questions and run scripts/validate-profile-lookup.js on value-free accounting. Redacted or unavailable lookups are access problems, not missing facts; optional unknown demographics may remain blank; live consent stays separate. Classify every visible answer as exact_profile, safe_derivation, supported_draft, missing_fact, live_consent, or forbidden_inference; validate the control type; fill only the first three; and ask only currently visible unresolved needs. Treat the current profile revision as reusable authority, never transcript, screenshot, parser, autocomplete, or cached values. Accessible-first is a hard scheduler invariant: park known authentication, account-creation, OTP, and pre-form-CAPTCHA work without starting a draft while an accessible candidate remains. Curated OPEN and recent accessibility never change allowedOperations to fill_form.' },
1977
1977
  }, {
1978
1978
  role: 'user',
1979
1979
  content: { type: 'text', text: 'Only active=true identifies resumable execution work. Active=false and preserved=true is terminal read-only reconciliation evidence.' },
@@ -1981,7 +1981,7 @@ function registerApplyTools(
1981
1981
  role: 'user',
1982
1982
  content: {
1983
1983
  type: 'text',
1984
- text: `Protocol 3.7.0 reliability gate for new work: require MCP contract ${APPLY_CONTRACT.contractVersion} and skill 4.9.0. Consume the exact proposedWave with frozen accessKnowledge before opening any browser; same-key advance replay returns identical member IDs, order, and rationale. When nextAction is access_review, including ordinary OPEN or neutral proposals, display the exact access-review receipt and do not report exhaustion. For a nonempty proposal, obtain explicit approval for the unchanged ordered job IDs and server approval hash before probing. For an all-deferred or recovery-blocked proposal with zero members, show the deferred count and stable job/company/provider deferment IDs, offer clear-deferment only for explicitly returned IDs, stop, or expiry, and never send an empty approval. Defer or clear only through jobId-scoped job, company, or provider tools; provider scope applies across companies until explicitly cleared. Never submit provider names, URLs, or raw chat. After complete local context loss, list bounded recovery candidates, obtain explicit confirmation of the exact set, and recover only that set. An active personal deferment blocks exact recovery until cleared. Treat tab recovery, form-state recovery, and mutation authority as independent. List active handoff receipts for the execution before resolving grouped submission statements; use the named receipt or the sole returned active receipt, classify every member, and claim that receipt before recording outcomes. Validate tab keep sets and resume upload stages locally. Never send raw browser values or click Submit.`,
1984
+ text: `Protocol 3.7.0 reliability gate for new work: require MCP contract ${APPLY_CONTRACT.contractVersion} and skill 4.9.1. Consume the exact proposedWave with frozen accessKnowledge before opening any browser; same-key advance replay returns identical member IDs, order, and rationale. When nextAction is access_review, including ordinary OPEN or neutral proposals, display the exact access-review receipt and do not report exhaustion. For a nonempty proposal, obtain explicit approval for the unchanged ordered job IDs and server approval hash before probing. For an all-deferred or recovery-blocked proposal with zero members, show the deferred count and stable job/company/provider deferment IDs, offer clear-deferment only for explicitly returned IDs, stop, or expiry, and never send an empty approval. Defer or clear only through jobId-scoped job, company, or provider tools; provider scope applies across companies until explicitly cleared. Never submit provider names, URLs, or raw chat. After complete local context loss, list bounded recovery candidates, obtain explicit confirmation of the exact set, and recover only that set. An active personal deferment blocks exact recovery until cleared. Treat tab recovery, form-state recovery, and mutation authority as independent. List active handoff receipts for the execution before resolving grouped submission statements; use the named receipt or the sole returned active receipt, classify every member, and claim that receipt before recording outcomes. Validate tab keep sets and resume upload stages locally. Never send raw browser values or click Submit.`,
1985
1985
  },
1986
1986
  }, {
1987
1987
  role: 'user',
@@ -1999,7 +1999,7 @@ function registerApplyTools(
1999
1999
  role: 'user',
2000
2000
  content: {
2001
2001
  type: 'text',
2002
- text: 'Browser preservation clarification: The following conditional rules supersede any unconditional complete-inventory wording earlier in this prompt. For the session-finalizer path, require complete controller and user inventories, build the non-empty keep list, and run the finalizer once. For the documented per-tab durable-handoff path, do not require unavailable inventories; preserve each ledger-mapped live tab with an exact persistence receipt. If no mapped live application tabs remain, skip both finalization and per-tab handoff. For reachability and visibility on the per-tab path, an exact current tab-bound user-visible handoff receipt is valid alternative proof. A user-confirmed direct tab closure may retire its ledger entry only after either complete-union absence or an exact current tab-bound user-side closure/absence receipt. Agent-initiated closure still requires the full close-proof gate. Policy 4.9.0 also accepts the documented markHandoff path described in the installed skill references/handoff-compatibility.md; this path supersedes earlier receipt-only readiness requirements. Before form mutation, verify that the runtime documentation promises to keep the tab across normal turn cleanup and that every mapped application tab is available. Bind each exact job/run/tab, await its markHandoff(), and check the controller inventory and user inventory where exposed; failed calls or missing tabs block mutation. Before ending every turn, await markHandoff() for every mapped live application tab, then check the controller inventory and user inventory where exposed. Failed marks or missing tabs block the handoff. Report incomplete inventories as unverified, never as closure proof. On the next turn, reclaim each exact tab, recheck identity and required fields, and re-mark before any later handoff. markHandoff returns Promise<void>; successful completion and inventory checks are observations, not a native persistence receipt or proof that draft state survives a crash. Never label mark-only evidence durable_handoff_receipt or change validators to manufacture receipt proof. Keep manual Submit, visible form verification, and the installed skill platform capability requirements.',
2002
+ text: 'Browser preservation clarification: The following conditional rules supersede any unconditional complete-inventory wording earlier in this prompt. For the session-finalizer path, require complete controller and user inventories, build the non-empty keep list, and run the finalizer once. For the documented per-tab durable-handoff path, do not require unavailable inventories; preserve each ledger-mapped live tab with an exact persistence receipt. If no mapped live application tabs remain, skip both finalization and per-tab handoff. For reachability and visibility on the per-tab path, an exact current tab-bound user-visible handoff receipt is valid alternative proof. A user-confirmed direct tab closure may retire its ledger entry only after either complete-union absence or an exact current tab-bound user-side closure/absence receipt. Agent-initiated closure still requires the full close-proof gate. Policy 4.9.1 also accepts the documented markHandoff path described in the installed skill references/handoff-compatibility.md; this path supersedes earlier receipt-only readiness requirements. Before form mutation, verify that the runtime documentation promises to keep the tab across normal turn cleanup and that every mapped application tab is available. Bind each exact job/run/tab, await its markHandoff(), and check the controller inventory and user inventory where exposed; failed calls or missing tabs block mutation. Before ending every turn, await markHandoff() for every mapped live application tab, then check the controller inventory and user inventory where exposed. Failed marks or missing tabs block the handoff. Report incomplete inventories as unverified, never as closure proof. On the next turn, reclaim each exact tab, recheck identity and required fields, and re-mark before any later handoff. markHandoff returns Promise<void>; successful completion and inventory checks are observations, not a native persistence receipt or proof that draft state survives a crash. Never label mark-only evidence durable_handoff_receipt or change validators to manufacture receipt proof. Keep manual Submit, visible form verification, and the installed skill platform capability requirements.',
2003
2003
  },
2004
2004
  }, {
2005
2005
  role: 'user',
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "trackly-cli",
3
- "version": "0.20.0",
3
+ "version": "0.20.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "trackly-cli",
9
- "version": "0.20.0",
9
+ "version": "0.20.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "1.32.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trackly-cli",
3
- "version": "0.20.0",
3
+ "version": "0.20.1",
4
4
  "mcpName": "io.github.trackly-app/trackly",
5
5
  "description": "AI job search CLI + hosted MCP server with OAuth. 250K+ jobs, 5,400+ companies, 40+ ATS. Works with Claude, ChatGPT, Cursor, Windsurf, Codex via hosted streamable-http or local stdio.",
6
6
  "bin": {
package/server.json CHANGED
@@ -17,12 +17,12 @@
17
17
  ]
18
18
  }
19
19
  ],
20
- "version": "0.20.0",
20
+ "version": "0.20.1",
21
21
  "packages": [
22
22
  {
23
23
  "registryType": "npm",
24
24
  "identifier": "trackly-cli",
25
- "version": "0.20.0",
25
+ "version": "0.20.1",
26
26
  "runtimeHint": "npx",
27
27
  "runtimeArguments": [
28
28
  {
@@ -9,7 +9,7 @@ Use Trackly as the source of truth for profile answers, documents, queue decisio
9
9
 
10
10
  ## Skill version
11
11
 
12
- Skill version: `4.9.0`. Before browser readiness read [references/handoff-compatibility.md](references/handoff-compatibility.md). This policy takes precedence over returned-persistence-receipt or finalizer requirements elsewhere when using the documented markHandoff path. Other review and safety gates remain unchanged.
12
+ Skill version: `4.9.1`. Before browser readiness read [references/handoff-compatibility.md](references/handoff-compatibility.md). This policy takes precedence over returned-persistence-receipt or finalizer requirements elsewhere when using the documented markHandoff path. Other review and safety gates remain unchanged.
13
13
 
14
14
  ## Non-negotiable rules
15
15
 
@@ -39,7 +39,7 @@ value-free phase receipt with `scripts/validate-phase-checkpoint.js` before
39
39
  claiming that phase complete.
40
40
  Read [references/legal-clarifications.md](references/legal-clarifications.md) when a form asks for a legal, regulatory, consent, or employer-relationship decision.
41
41
 
42
- 1. Call `trackly_get_apply_protocol`. Skill 4.9.0 requires protocol 3.7.0 or newer for new reliability work. Protocol 3.2 remains valid only for an already-active explicit legacy single run; an already-active explicit 3.2 single run may finish through its legacy path. Preserve the protocol's documented recovery paths for already-active older work. Require `compatibleSkillMajor: 4` and `compatibleSkillMinimumVersion` no newer than this installed skill. Reject an older or incompatible version for new work and report that the backend must finish updating or `trackly agent setup` must update the skill. Protocol 3.2 added exact-origin trust for jobs Trackly ingested directly from employer careers sources; do not recreate the retired ownership-timestamp gate in the client.
42
+ 1. Call `trackly_get_apply_protocol`. Skill 4.9.1 requires protocol 3.7.0 or newer for new reliability work. Protocol 3.2 remains valid only for an already-active explicit legacy single run; an already-active explicit 3.2 single run may finish through its legacy path. Preserve the protocol's documented recovery paths for already-active older work. Require `compatibleSkillMajor: 4` and `compatibleSkillMinimumVersion` no newer than this installed skill. Reject an older or incompatible version for new work and report that the backend must finish updating or `trackly agent setup` must update the skill. Protocol 3.2 added exact-origin trust for jobs Trackly ingested directly from employer careers sources; do not recreate the retired ownership-timestamp gate in the client.
43
43
  2. Call `trackly_get_profile_onboarding` or fetch both the profile schema and application profile. When present, render `schema.screens` in ascending `order` as one grouped question packet per screen. Within a screen, preserve category `order` and then field `order`; use each field's user-facing `rationale` when the user asks why it is needed. Ask only unknown or confirmation-needed fields and honor `consistencyRules` before submitting profile changes, resolving contradictions with the user instead of guessing. When `schema.screens` is absent on a legacy backend, fall back to the existing category-based onboarding behavior. Treat `completeness.percent` as required onboarding readiness only. Use `coverage.missingReusableKeys` to explain reusable optional gaps, while `coverage.contextualKeys` are intentionally asked only on the relevant employer form. Do not claim that 100% required completeness answers every possible application question.
44
44
  3. Save answers with `trackly_update_application_profile`:
45
45
  - Use `answered`, `intentionally_blank`, `declined`, or `unknown` exactly.
@@ -85,7 +85,7 @@ Read [references/legal-clarifications.md](references/legal-clarifications.md) wh
85
85
  - For each fixed batch member, preserve an explicit job ID -> application run ID -> browser tab mapping. Complete the full start -> conditional resume preparation/confirmation/verification when an upload control exists -> form completion -> `review_ready` lifecycle for every member. A review-ready run does not block the next member. Never submit any of them.
86
86
  6. When the selected job or current fixed batch member has no `runId`, call `trackly_start_apply_run` with the complete `batchId`, `memberId`, `expectedMemberVersion`, `expectedInspectionEpoch`, and `leaseToken` returned by Trackly. This is the sanctioned idempotent lookup for a recovered member whose `runId` is absent; call it with the exact recovered binding and Trackly will reuse the bound active run. When the member already has a `runId`, do not call `trackly_start_apply_run` in this or any subsequent start step: reuse that exact run and bind or recover its browser surface through `trackly_bind_apply_surface` as required. Never create a replacement run because browser control was interrupted.
87
87
  - If a bound start returns a transport failure, a non-access HTTP 5xx response, or an error explicitly marked `retryable: true`, preserve the frozen member and browser state. Refetch the active batch, renew its lease, and retry the same complete binding once. Classify the retry response independently with these same rules: route canonical `maintenance_mode` or legacy `planned_maintenance` directly through **Resume after maintenance**; surface controlled-access/request errors marked `retryable: false` and every other HTTP 4xx response unchanged; only a second transport failure, non-access HTTP 5xx response, or explicitly retryable error becomes `backend_run_start_unavailable`. Route maintenance on either attempt without consuming or relabeling the retry, and never relabel a permanent retry response as an outage. For `backend_run_start_unavailable`, continue other members and report a Trackly control-plane failure. Do not call `trackly_checkpoint_apply_batch` for this condition because start failure has not produced the required run ID. The unchanged frozen member is the durable resume point. Never switch that frozen member to an unbound legacy run or blame the employer form.
88
- - Require `run.protocolVersion` to be 3.1.0 or newer and to share protocol major 3 with the fetched protocol. A new reliability execution member requires 3.7.0 or newer; already-active older work may use only the recovery path published by its fetched protocol. Never continue a pre-evidence 3.0.x run under skill 4.9.0. Preserve that run instead of starting a replacement, record it `blocked` with a value-free protocol-upgrade reason when possible, and tell the user the saved job can be retried only after the stale run is cleared through Trackly's supported lifecycle. Stop and refetch the protocol and active execution or batch if support level, execution mode, provider, required scenarios, authorized origin policy, member version, or inspection epoch changes after run creation.
88
+ - Require `run.protocolVersion` to be 3.1.0 or newer and to share protocol major 3 with the fetched protocol. A new reliability execution member requires 3.7.0 or newer; already-active older work may use only the recovery path published by its fetched protocol. Never continue a pre-evidence 3.0.x run under skill 4.9.1. Preserve that run instead of starting a replacement, record it `blocked` with a value-free protocol-upgrade reason when possible, and tell the user the saved job can be retried only after the stale run is cleared through Trackly's supported lifecycle. Stop and refetch the protocol and active execution or batch if support level, execution mode, provider, required scenarios, authorized origin policy, member version, or inspection epoch changes after run creation.
89
89
  - In guided mode, inspect the page before preparing any resume bytes. Confirm the employer, role, HTTPS origin, reachable review path, semantic controls, whether an attachment control exists, and absence of a credential, verification, CAPTCHA, or submit-only wall. A missing file input is not itself a blocker; skip the resume path when the application has no attachment control. Any other failed precondition is an execution blocker, not permission to improvise.
90
90
  7. Pass the browser readiness gate before preparing resume bytes:
91
91
  - Use semantic browser control through Codex in-app browser controls, Chrome MCP/extension browser control, or Claude in Chrome.
@@ -36,7 +36,9 @@ an observation.
36
36
 
37
37
  Inventory all visible questions first. Map their canonical keys against the current schema, including optional diversity fields. Fetch one current contextual application profile with sensitive values when existing storage consent permits, supplying the actual provider, company ID and jurisdiction. Reuse this fetch for the packet; do not ask from an incomplete compact projection. If required values are redacted or unavailable, report the access limitation and recover it instead of calling the answer unknown.
38
38
 
39
- For each visible control, retain a value-free receipt with its fingerprint, whether schema and relevant profile projection were fetched, resolved state (`answered`, `unknown`, `redacted`, `unavailable`, or `live_consent`), required flag, intended disposition (`fill`, `preserve`, `ask`, `defer_optional`, or `blocked`), and committed flag. Run `node scripts/validate-profile-lookup.js receipt.json` before presenting a packet. This validator checks local accounting; it does not call Trackly or prove a fetch happened. Retain actual lookup and committed-control evidence locally. Answered compatible fields must be filled and verified or preserve a user edit; they cannot appear in the questions. Optional unknown demographics may stay blank without interrupting the user. Required unknown facts and genuinely live decisions can be asked together after known answers commit. An unavailable profile lookup is a lookup problem, never evidence that the user has no saved answer.
39
+ For each visible control, retain a value-free receipt with its fingerprint, whether schema and relevant profile projection were fetched, resolved state (`answered`, `unknown`, `redacted`, `unavailable`, or `live_consent`), required flag, intended disposition (`fill`, `preserve`, `ask`, `defer_optional`, or `blocked`), and committed flag. Run `node "<skill-dir>/scripts/validate-profile-lookup.js" receipt.json` before presenting a packet. This validator checks local accounting; it does not call Trackly or prove a fetch happened. Retain actual lookup and committed-control evidence locally. Answered compatible fields must be filled and verified or preserve a user edit; they cannot appear in the questions. Optional unknown demographics may stay blank without interrupting the user. Required unknown facts and genuinely live decisions can be asked together after known answers commit. An unavailable profile lookup is a lookup problem, never evidence that the user has no saved answer.
40
+ Resolve `<skill-dir>` to the loaded skill’s absolute directory before invoking the command, regardless of the application repository working directory. Include explicit `workMode` (`accessible_execution` or `fixed_inspection`) in the value-free lookup receipt. `profileRevision` must be a positive safe integer for accessible execution; fixed inspection also permits zero. Missing or unknown work mode fails closed.
41
+
40
42
 
41
43
  For diversity surveys check the schema's gender identity, transgender, sexual orientation, ethnicity, age range, disability, veteran and any other visible concepts. Match supported option synonyms, such as Hispanic/Latino to Hispanic/Latine, without inventing identity. A negative disability or veteran answer excludes that option; it does not prove “None of the above” for a multi-select community question that also asks about parenthood, immigration or neurodiversity. Leave unsupported optional options unselected.
42
44
 
@@ -1,4 +1,4 @@
1
- # Browser handoff compatibility — 4.9.0
1
+ # Browser handoff compatibility — 4.9.1
2
2
 
3
3
  This preservation-only policy supersedes contradictory returned-receipt and finalizer requirements in this skill. All backend, submission, resume, origin, ownership, form integrity, and actual visibility gates remain unchanged. Never fabricate evidence.
4
4
 
@@ -419,8 +419,9 @@ function validateSelection(receipt, expectedContext) {
419
419
  const normalized = receipt.approvedJobIds.filter((id) => Number.isSafeInteger(id) && id > 0);
420
420
  if (normalized.length !== receipt.approvedJobIds.length) errors.push('approvedJobIds must contain positive safe integers');
421
421
  if (new Set(normalized).size !== normalized.length) errors.push('approvedJobIds must be unique');
422
- if (receipt.approvedJobIds.length === 0 && receipt.queueExhausted !== true) {
423
- errors.push('approvedJobIds may be empty only when queueExhausted is true');
422
+ if (receipt.approvedJobIds.length === 0
423
+ && (receipt.workMode !== 'accessible_execution' || receipt.queueExhausted !== true)) {
424
+ errors.push('approvedJobIds may be empty only for accessible_execution when queueExhausted is true');
424
425
  }
425
426
  }
426
427
  requireTrue(errors, receipt, 'approvalRecorded');
@@ -3,8 +3,9 @@
3
3
  const fs = require('node:fs');
4
4
  function validate(receipt) {
5
5
  const errors = [];
6
- if (!receipt || !Number.isSafeInteger(receipt.profileRevision) || receipt.profileRevision < 1 || !Array.isArray(receipt.controls) || !receipt.controls.length) return ['invalid_receipt'];
7
- if (Object.keys(receipt).some(k => !['profileRevision', 'controls'].includes(k))) errors.push('unexpected_receipt_fields');
6
+ if (!receipt || !Number.isSafeInteger(receipt.profileRevision) || receipt.profileRevision < (receipt.workMode === 'fixed_inspection' ? 0 : 1) || !Array.isArray(receipt.controls) || !receipt.controls.length) return ['invalid_receipt'];
7
+ if (Object.keys(receipt).some(k => !['workMode', 'profileRevision', 'controls'].includes(k))) errors.push('unexpected_receipt_fields');
8
+ if (!['accessible_execution', 'fixed_inspection'].includes(receipt.workMode)) errors.push('invalid_work_mode');
8
9
  const seen = new Set();
9
10
  for (const c of receipt.controls) {
10
11
  if (!c || typeof c !== 'object' || Array.isArray(c)) { errors.push('invalid_control'); continue; }