# Worked example: AMS1117, end to end

The build that produced [adom/ams-ams1117](https://wiki.adom.inc/adom/ams-ams1117) and
[adom/umw-ams1117](https://wiki.adom.inc/adom/umw-ams1117), in order, including the two
places it went wrong first.

## 0. What made this a good test case

`AMS1117` is a jellybean 1 A LDO whose part number is second-sourced. It exercises
every hard part of the skill: a datasheet family (six voltages, three packages), a
manufacturer collision, a footprint whose tab is an electrical net, and two existing
per-variant pages that should never have been created.

## 1. Get the datasheet, then read it before anything else

The datasheet is the page boundary (SKILL.md section 1), so it comes first.

```sh
adom-desktop --ai-thread "<thread>" desktop_list_files \
  '{"path":"C:\\Users\\<user>\\Downloads","glob":"*1117*"}'
adom-desktop --ai-thread "<thread>" pull_file \
  '{"filePaths":["C:\\Users\\<user>\\Downloads\\ds1117.pdf"],"destDir":"/tmp"}'
```

Then Read the PDF with the `pages` parameter and take the ordering table, the
electrical characteristics tables and the package drawings.

> A stalled Chrome download shows up as `Unconfirmed NNNNNN.crdownload` with no
> extension. It is a complete file. Check the magic bytes rather than assuming the
> download failed.

## 2. Decide the boundary

The AMS ordering table lists 1.5 / 1.8 / 2.5 / 2.85 / 3.3 / 5.0 V across SOT-223,
TO-252 and 8-lead SOIC. That is **one page**.

Two existing pages, `adom/ams1117-3-3` and `adom/ams1117-1-2`, were per-variant
splits of that same family. They should not have existed.

Then the second datasheet arrived: **UMW / Youtai Semiconductor**, same part number,
carrying 1.2 V and not 2.85 V, SOT-89 instead of SO-8, 18 V input maximum instead of
15 V, 2.1 to 2.5 A current limit instead of 0.9 to 1.5 A, and thermal shutdown at
150 C instead of 165 C.

**The first attempt merged both onto one page** with a comparison table and an
"available from" column per variant. That was rejected, correctly: a merged page needs
a vendor caveat on every number, which is what gets misread. Two datasheets, two pages.

## 3. CAD, pulled not authored

All three AMS packages and all three UMW packages exist in KiCad 10's official library
on the user's machine, with matching STEP models.

```sh
adom-desktop --ai-thread "<t>" desktop_list_files \
  '{"path":"C:\\Program Files\\KiCad\\10.0\\share\\kicad\\footprints\\Package_TO_SOT_SMD.pretty","glob":"SOT-223*"}'

adom-desktop --ai-thread "<t>" pull_file '{"filePaths":[
 "C:\\Program Files\\KiCad\\10.0\\share\\kicad\\footprints\\Package_TO_SOT_SMD.pretty\\SOT-223-3_TabPin2.kicad_mod",
 "C:\\Program Files\\KiCad\\10.0\\share\\kicad\\3dmodels\\Package_TO_SOT_SMD.3dshapes\\SOT-223.step"
],"destDir":"/tmp"}'
```

`SOT-223-3_TabPin2` and not plain `SOT-223`, because the AMS1117 tab **is VOUT**,
internally bonded to pin 2. The existing `adom/ams1117-3-3` page shipped a SnapEDA
pattern with the tab on pad 4 as its own net, which leaves the heat path floating.

Rename both the node and the Value property:

```python
t = t.replace('(footprint "SOT-223-3_TabPin2"', '(footprint "AMS1117_SOT-223"', 1)
t = re.sub(r'\(property "Value" "[^"]*"', '(property "Value" "AMS1117_SOT-223"', t, count=1)
t = re.sub(r'\(model "[^"]*"', '(model "${KIPRJMOD}/ams1117-sot223.step"', t)
```

Then:

```sh
step2glb convert ams1117-sot223.step --out ams1117-sot223.glb

cat > sym.json <<'JSON'
{"symbolName":"AMS1117","manufacturer":"Advanced Monolithic Systems","package":"SOT-223",
 "description":"AMS1117 1 A low-dropout linear regulator","designatorPrefix":"U",
 "datasheetUrl":"http://www.advanced-monolithic.com/pdf/ds1117.pdf","footprint":"AMS1117_SOT-223",
 "pins":[{"number":"3","name":"VIN","type":"power_in","side":"left"},
         {"number":"2","name":"VOUT","type":"power_out","side":"right"},
         {"number":"1","name":"GND/ADJ","type":"power_in","side":"bottom"}]}
JSON
adom-symbol create --file sym.json --out ./sym
adom-lbr import-kicad --sym ams1117.kicad_sym --fp ams1117-sot223.kicad_mod --mpn AMS1117 --out ams1117.adom-lbr.json
```

## 4. Viewers, with the fab-layer workaround

```sh
adom-symbol embed --file ams1117.kicad_sym --out viewer-symbol.html

for f in sot223 to252 so8; do
  adom-footprint embed --file ams1117-$f.kicad_mod --out /tmp/raw-$f.html
  python3 scripts/inject_layers.py /tmp/raw-$f.html ams1117-$f.kicad_mod fp-$f.html
done
python3 scripts/build_switcher.py . AMS viewer-footprints.html
```

Without `inject_layers.py` the viewer shows floating pads with no body outline,
because adom-footprint 1.0.20 emits the fab, silk and courtyard groups empty
(adom/adom-footprint#2). The viewer's own `LAYER_DEFS` already defines all three and
`groupHasGeo()` shows a row as soon as a group holds geometry, so filling the groups
is the entire fix.

## 5. Hero

three.js plus puppeteer, GLB rendered as a 3/4 product shot inside a floating window,
composited into a billboard on the brand tokens. Two gotchas:

- puppeteer needs `--allow-file-access-from-files` because the three.js importmap uses
  `file://` URLs, and the script must run where `node_modules` resolves (symlink it
  into the scratchpad).
- The SOT-223 GLB needed `root.rotation.z = Math.PI` to face its three leads forward
  instead of the tab. That is an in-plane spin applied before the Z-up
  `rotation.x = -Math.PI/2`, under Euler XYZ order.

## 6. Publish both layers

```sh
adom-wiki pkg publish --org adom --public --include-media
adom-wiki repo push adom/ams-ams1117 -m "AMS1117 (Advanced Monolithic Systems) component page" \
  --files page.json README.md readme.html ams1117.kicad_sym ams1117-so8.kicad_sym \
  ams1117-sot223.kicad_mod ams1117-to252.kicad_mod ams1117-so8.kicad_mod \
  ams1117-sot223.step ams1117-to252.step ams1117-so8.step \
  ams1117-sot223.glb ams1117-to252.glb ams1117-so8.glb ams1117.adom-lbr.json \
  viewer-symbol.html viewer-footprints.html docs/ams1117-datasheet-ams.pdf \
  screenshots/hero.png screenshots/datasheet-cover.png
```

The registry lowercases slugs, so publishing `AMS-AMS1117` yields `ams-ams1117`.
Write the cross-links lowercase from the start.

## 7. Verify live, not locally

```sh
curl -s -o /dev/null -w "%{http_code}\n" \
  https://wiki.adom.inc/api/v1/pages/adom/ams-ams1117/files/readme.html
```

Then screenshot. The first live capture of the footprint switcher came back blank and
looked like a CSP problem; it was puppeteer painting before the large `srcdoc` iframes
had rendered. Wait about 5 s after `networkidle2`. Diff live against local by
**character** count, because µ and Ω make byte counts differ on identical files.

## 8. Deprecate what this replaced

The combined `adom/ams1117` page became wrong once the split happened. A banner in the
readme was not enough: it renders far below the fold and the header looked live. What
made it visibly deprecated (SKILL.md section 8):

```sh
# title -> "[DEPRECATED] 1 A Low-Dropout Regulator - AMS1117 → ams-ams1117 / umw-ams1117"
# tags  -> ["deprecated","alias","ams-ams1117","umw-ams1117", ...]
# brief -> leads with "DEPRECATED. Use ..."
# hero  -> replaced with a struck-through signpost image
adom-wiki repo push adom/ams1117 --files page.json -m "..."
adom-wiki pkg publish --org adom
for v in 1.0.0 1.1.0 1.2.0 1.2.1 1.2.2; do
  adom-wiki pkg deprecate "adom/ams1117@$v" "Split by manufacturer: use adom/ams-ams1117 or adom/umw-ams1117."
done
```

`json.dumps` escapes the arrow to `\u2192` unless you pass `ensure_ascii=False`.

## 9. Chase the dependents

Repointing is a registry-layer change, so it needs a `pkg publish` on each dependent,
not a repo push. Issues were filed on every page that depended on the old slugs rather
than editing other people's boards:

- `adom/ams1117-3-3` and `adom/ams1117-1-2`: deprecate, pointing at the vendor page
  that matches the silicon. 1.2 V is UMW-only, so that one is unambiguous.
- `adom/ams1117-3v3-molecule` and `adom/large-automotive-eth-switch-molecule`:
  repoint the dependency, and check the tab pad is on the VOUT net given the wrong
  footprint they inherited.

## What was found along the way

Two real defects in pages that already existed, both now written into issues:

1. `adom/ams1117-3-3` ships a footprint with **the tab on pad 4 as its own net**. The
   tab is VOUT (pin 2).
2. `adom/ams1117-1-2` ships a footprint that is **entirely on back layers**
   (B.Cu / B.Mask / B.Paste / B.SilkS / B.Fab / B.CrtYd) with no front geometry at
   all. Anything placed from it lands bottom-side.

Both are the kind of thing that only surfaces when someone rebuilds a page against the
datasheet. That is the argument for this skill existing.
