# Hk Share Award Tax Dipn38

> Compute Hong Kong salaries tax partial exemption for share awards (GSU / RSU / stock options) under DIPN No. 38 paragraphs 43-46 and section 8(1A)(a) of the Inland Revenue Ordinance. Full lifecycle: (1) auto-extract vest data from Morgan Stanley / IRD / IR56B via Chrome MCP, (2) compute DIPN 38 time apportionment, (3) cross-check IR56B vs IRD assessment to detect unclaimed exemptions, (4) generate APPENDIX-EQUITY PDF for eTAX submission, (5) generate HTML audit report for personal review, (6) guide eTAX BIR60 filing or 70A retrospective claim. Triggers: HK salaries tax, BIR60, IR56B, share award apportionment, DIPN 38, 'partial exemption', cross-border GSU/RSU vest, '报税分析', '股票减税', 'GSU 豁免', '从内地转来香港', '70A', 'time apportionment', '股票报税'.

- Skill: `yangwhale/hk-share-award-tax-dipn38` (Agent Skill, multi-file: 14 files)
- Install (CLI): `npx skillmds@latest add yangwhale/hk-share-award-tax-dipn38`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yangwhale/hk-share-award-tax-dipn38/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: yangwhale (https://skillmd.com/u/yangwhale)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yangwhale/hk-share-award-tax-dipn38

---


# Hong Kong Share Award Tax — DIPN 38 Partial Exemption

When a Hong Kong taxpayer transfers from a non-HK employer to a HK employer mid-vesting, share awards granted under the non-HK employment are only partially taxable in HK. This skill produces:

1. An **IR56B vs Assessment cross-check** — detect which tax years have unclaimed exemptions
2. A **DIPN 38 computation PDF** in the IRD-accepted "APPENDIX-EQUITY" format
3. An **HTML audit report** for personal review (CC Pages)
4. The **eTAX BIR60 Appendix Section 4** filing guidance
5. An **IR831 / Section 70A** retrospective claim package (for years where exemption was missed)

---

## When to trigger

Strong triggers:
- User mentions HK salaries tax + share awards / GSU / RSU / stock options
- User mentions "DIPN 38" / "partial exemption" / "section 8(1A)(a)"
- User mentions transfer between non-HK and HK entities (Google Shanghai → Google HK, etc.)
- User uploads a stock statement / IR56B / IRD assessment and asks about HK tax
- Chinese: "报税分析", "股票减税", "GSU 豁免", "地域来源", "从内地转来香港", "70A", "股票报税"

Do NOT use for:
- Non-HK tax jurisdictions
- Pure HK employment with no cross-border element
- Carried Interest (BIRSP4 — different form)

---

## Core algorithm

Legal basis: **DIPN No. 38 ¶43–46** + **section 8(1A)(a) IRO**.

```
                                    Days in HK during vesting period
Net Assessable HKD = Net Amount × ─────────────────────────────────────
                                    Total days in vesting period
```

Where:
- Total days = `vest_date − grant_date` (Python `.days`)
- Outside-HK days = `hk_employment_start − grant_date` (when grant < hk_start)
- HK days = total − outside

**Decision rules**:
| Grant date | Treatment |
|---|---|
| Before HK employment start | Apportion (this skill's main work) |
| On or after HK employment start | 100% assessable (no apportionment) |

**Critical data rules** (verified against IRD-accepted filings):
- Use **`Total Income of GSUs at Vest`**, NOT `Prorated Income` (Prorated is employer-internal)
- Use **HK jurisdiction row's FX rate** (~7.7), NOT China row's PBOC rate (~7.1)
- Use **floor()** (truncate) for final integer, not round() — IRD convention
- Google IR56B reports GSU at **full amount** (no geographic split) — taxpayer must self-claim

---

## Workflow

### Phase 1: Gather inputs

Collect via dialogue; auto-fetch where possible:

| Material | Source | Required |
|---|---|---|
| Morgan Stanley Stock Statement | User sends PDF/CSV, or Chrome MCP from atwork.morganstanley.com | **Yes** |
| IR56B (each tax year) | User sends PDF, or Payday system | **Yes** |
| IRD Assessment notices | Chrome MCP from itp.etax.ird.gov.hk, or user sends PDF | **Yes** |
| HK employment start date | User states / IR56B period / Vialto docs | **Yes** |
| Taxpayer name & IRD file no. | IR56B / assessment notice | **Yes** |
| Phone number | User states (for IR831) | Only for 70A |
| Previous year's tax return | User / Vialto | Optional (algorithm verification) |

**Auto-fetch via Chrome MCP** (if user has logged in):
- Morgan Stanley: Activity → Reports → "Your Alphabet Stock Statement" → All history / USD / CSV → Run Report → fetch download link
- IRD: itp.etax.ird.gov.hk → 税務狀況 → 評税 → 檢視 → presign URL → fetch PDF

### Phase 2: Extract vest data from stock statement

For Alphabet/Google statements, see [references/extracting_alphabet_statement.md](references/extracting_alphabet_statement.md).

Key rules:
- Take **Hong Kong jurisdiction rows only** (skip China rows — different FX rate)
- Extract: `grant_date`, `vest_date`, `shares` (GSUs Vested), `fmv_usd` (Fair Market Value), `fx_rate`
- Filter to the target year of assessment (vest_date ∈ [YA_start, YA_end])
- Output CSV for `scripts/compute.py`

### Phase 3: Cross-check IR56B vs Assessment (detect unclaimed exemptions)

**This is the diagnostic step** — determines whether to file a new claim or a retrospective 70A correction.

For each assessed tax year:
```
IF IR56B Total = Assessment income → ❌ No exemption claimed (problem year)
IF IR56B Total > Assessment income → ✅ Exemption was claimed (OK year)
   Verify: difference ≈ independently computed CN-source amount (within 2%)
```

### Phase 4: Verify algorithm against prior year (optional but recommended)

If user provided a previous year's return with APPENDIX-EQUITY:
1. Re-run `compute.py` on last year's data
2. Compare each row's `assessable_hkd` to the filed figure
3. Must match within HK$ 0.01 — if not, stop and investigate

### Phase 5: Run computation

Build config YAML + vests CSV, then:

```bash
python3 scripts/compute.py --config config.yaml --vests vests.csv --output result.json
```

Validates all vests fall within YA window, computes per-vest apportionment, aggregates totals, runs sanity checks.

### Phase 6: Generate outputs

**APPENDIX-EQUITY PDF** (for eTAX submission):
```bash
python3 scripts/gen_pdf.py --result result.json --output appendix_equity.pdf
```
Multi-page PDF: main table → DIPN 38 detail blocks → Itinerary appendix.

**HTML audit report** (for personal review):
```bash
python3 scripts/gen_tax_report.py \
  --analysis analysis.json \
  --ir56b '{"2024/25":{"gsu":604498,"total":3305748}}' \
  --assessment '{"2024/25":3305748}' \
  --taxpayer "NAME" --file-no "FILE_NO" \
  --output report.html
```
Publish via `publish-cc-page.sh`.

### Phase 7: Action guidance

**Situation A — Current year filing (not yet filed)**:
- Guide eTAX BIR60 filing per [references/etax_filing.md](references/etax_filing.md)
- Enable "Apply for partial exemption" in Step 2 → Box 30 = IR56B total → Box 34 = excluded amount → Section 4 attach PDF

**Situation B — Past year where exemption was missed (70A retrospective)**:
- Guide IR831 + Section 70A letter per [references/ir831-guide.md](references/ir831-guide.md)
- IR831 Item 2 + Item 25, attach APPENDIX-EQUITY PDF + IR56B + employment contract
- Deadline: 6 years after end of tax year

**Situation C — All years correctly claimed**:
- Confirm no action needed; remind to continue claiming until all pre-transfer grants vest

---

## Reference files

- [references/dipn38.md](references/dipn38.md) — DIPN 38 ¶43–46 verbatim + interpretation
- [references/etax_filing.md](references/etax_filing.md) — Full eTAX BIR60 filing walkthrough (Box-by-Box)
- [references/ir831-guide.md](references/ir831-guide.md) — IR831 filling guide + 70A letter template
- [references/extracting_alphabet_statement.md](references/extracting_alphabet_statement.md) — Morgan Stanley statement parsing
- [references/workflow-checklist.md](references/workflow-checklist.md) — Material checklist + decision tree

## Scripts

- `scripts/compute.py` — Core DIPN 38 calculation engine (YAML+CSV → JSON)
- `scripts/gen_pdf.py` — APPENDIX-EQUITY PDF generator (reportlab)
- `scripts/gen_tax_report.py` — HTML audit report generator (Material Design)
- `scripts/parse_ms_statement.py` — Morgan Stanley CSV auto-parser (bulk extraction)
- `scripts/example/` — Working example with anonymized data

## Common pitfalls

| Pitfall | Fix |
|---|---|
| Used `Prorated Income` instead of `Total Income` | Always use `Total Income of GSUs at Vest` (gross) |
| Used China row's FX rate (~7.1) | Use HK row's FX rate (~7.7) |
| Used round() instead of floor() | Use `int()` (truncate) — IRD convention |
| Filed BIR-SP4 form | Wrong form — use BIR60 Appendix Section 4 |
| Selected wrong eTAX grounds | Always pick "Non-Hong Kong employment" section 8(1A)(a) |
| Forgot to enable Box 34 in eTAX | Must tick "Apply for partial exemption" in Step 2 first |
| Forgot to attach PDF | The PDF is the proof; without it IRD may reject |
| Assumed Google IR56B splits by geography | Google reports full GSU amount — you must self-claim |
| Assumed Prorated = what to report | Prorated is employer-internal; IRD wants gross + your own apportionment |
| Didn't check if a tax agent already claimed | Check Vialto/PwC/Deloitte first — avoid duplication |

