Commit graph

205 commits

Author SHA1 Message Date
Jeffrey (Dongkyu) Kim
3bc3762195 Enable repeatable used-car price lookups from a rental-company source
Issue #46 required surveying major Korean rental companies before implementation and then choosing the easiest stable provider. SK렌터카 다이렉트 exposes 타고BUY inventory in public Next.js page data, so the feature stays dependency-free while still supporting live repeated lookups and documented provider rationale.

Constraint: Must compare major Korean rental companies before implementation
Constraint: Must verify 10+ live lookups against a real provider surface
Rejected: 롯데오토옥션 as v1 provider | public list contract was unstable and legacy .do flows returned inconsistent or 404 pages
Rejected: 레드캡렌터카 as v1 provider | no public used-car inventory or API surface was found
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep the v1 provider read-only and inventory-snapshot-based unless a stable documented public API is confirmed
Tested: npm run ci
Tested: Live 10-query run against https://www.skdirect.co.kr/tb at 2026-04-02T07:22:46Z
Tested: LSP diagnostics on affected files
Not-tested: Seller-specific detail drilldowns or non-SK providers
Related: #46
2026-04-02 16:26:04 +09:00
Jeffrey (Dongkyu) Kim
a5c9232b3f Keep Korean law completion guidance in sync with enforced lookups
The previous follow-up aligned the main skill examples, but the done-criteria text still left interpretation and ordinance routing implicit. This commit makes the completion checklist explicit and extends the doc regression so future edits cannot silently drop those lookup paths.

Constraint: Must stay within the existing issue #41 korean-law-mcp-only contract
Rejected: Leave the done checklist implicit | reviewers and future edits could drift from the enforced lookup set
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When the supported Korean-law lookup set changes, update the done checklist and regression together
Tested: node --test scripts/skill-docs.test.js
Not-tested: full CI before commit
2026-04-01 09:57:34 +09:00
Jeffrey (Dongkyu) Kim
b48ded279b Keep Korean law skill guidance aligned with supported lookups
The approved issue #41 feature already worked, but the shipped skill text still under-described ordinance and interpretation lookups compared with the documented capability set. This follow-up tightens the skill copy and locks that contract with a doc regression so the branch stays merge-ready without changing the underlying korean-law-mcp routing rules.

Constraint: Must preserve the existing korean-law-mcp-only and mode-specific LAW_OC setup contract
Rejected: Leave the skill wording as-is | drift from the documented lookup surface would remain
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep the skill examples and doc regression aligned whenever supported korean-law-mcp search surfaces change
Tested: node --test scripts/skill-docs.test.js
Not-tested: live LAW_OC-backed upstream API queries
2026-04-01 09:54:18 +09:00
Jeffrey (Dongkyu) Kim
06453dd1ee Keep the Korean law feature diff merge-ready
Verification uncovered trailing whitespace in the new korean-law feature guide when checking the branch diff. I added a regression to the skill docs suite and removed the whitespace so the approved documentation contract stays clean and reviewable.

Constraint: Preserve the existing korean-law-mcp + mode-specific LAW_OC contract without widening scope
Rejected: Leave the whitespace issue as-is | git diff --check stayed dirty on the branch
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep docs/features/korean-law-search.md free of trailing whitespace so diff hygiene stays enforced by the regression
Tested: node --test scripts/skill-docs.test.js; npx tsc --noEmit --pretty false --project /Users/jeffrey/Projects/k-skill/tsconfig.json; npm install -g korean-law-mcp && korean-law list && korean-law help search_law; npm run ci; git diff --check
Not-tested: Live credentialed LAW_OC search execution against the upstream API
2026-04-01 09:52:01 +09:00
Jeffrey (Dongkyu) Kim
e981a81e46 Clarify Korean law setup modes to avoid credential confusion
A review found the new korean-law-search docs treated LAW_OC as an unconditional prerequisite even though the upstream remote MCP endpoint is configured separately from the local CLI/server path. This update makes the docs and regression tests mode-specific: local CLI/MCP uses LAW_OC, while the remote endpoint stays a korean-law-mcp-only url fallback without a user-supplied credential.

Constraint: Upstream korean-law-mcp uses LAW_OC on the local CLI/server path while the documented remote MCP endpoint is configured with url only
Rejected: Keep LAW_OC mandatory for every korean-law-mcp mode | contradicts upstream docs and reviewer evidence
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep README/setup/skill docs and regression tests aligned on the local-vs-remote korean-law-mcp contract
Tested: node --test scripts/skill-docs.test.js; npm install -g korean-law-mcp && korean-law list && korean-law help search_law; npx tsc --noEmit --pretty false --project /Users/jeffrey/Projects/k-skill/tsconfig.json; npm run ci; lsp_diagnostics scripts/skill-docs.test.js
Not-tested: Live remote MCP endpoint connection against https://korean-law-mcp.fly.dev/mcp
2026-04-01 09:39:03 +09:00
Jeffrey (Dongkyu) Kim
d6411f6311 Route Korean law lookups through korean-law-mcp
Add a documentation-first korean-law-search skill and lock the repo docs around the rule that Korean law queries must go through korean-law-mcp rather than a new in-repo package.

The change updates install/setup/security guidance, publishes the new feature doc, and adds regression tests so future edits keep the LAW_OC + korean-law-mcp contract intact.

Constraint: Issue #41 requires korean-law-mcp for every Korean law lookup
Constraint: Must not add a new npm or python package in this repository
Rejected: Add a repo-local law package | violates the no-new-package requirement and duplicates upstream MCP work
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep Korean law lookup guidance pinned to korean-law-mcp unless issue requirements explicitly change
Tested: node --test scripts/skill-docs.test.js
Tested: npm install -g korean-law-mcp && korean-law list && korean-law help search_law
Tested: npm run ci
Tested: npx tsc --noEmit --pretty false --project /Users/jeffrey/Projects/k-skill/tsconfig.json
Not-tested: live search_law/get_law_text against a real LAW_OC credential
2026-04-01 09:14:55 +09:00
Jeffrey (Dongkyu) Kim
46fef0f873 Make Coupang shopper research usable without pretending scraping is stable
Coupang blocks unattended shopper queries in this environment, so the new package focuses on the durable pieces we can ship honestly: official URL builders, browser-captured HTML parsers, and explicit automation probes. The docs and skill now explain the seller-API limitation, the verified anti-bot behavior, and the browser-capture fallback expected by callers.

Constraint: No general shopper Open API surfaced in Coupang's official developer docs

Constraint: Headless/direct retrieval is anti-bot blocked in verified local probes

Rejected: Bundle a scraping bypass or hidden browser dependency | violates repo policy and would over-claim reliability

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Keep probe/docs behavior aligned with fresh live verification before claiming unattended Coupang access works

Tested: npm run ci; live probeAutomation(query=생수) with direct fetch + Playwright-core browserFetchHtml; LSP diagnostics on changed JS/test files

Not-tested: Headed/manual browser sessions with a human-authenticated Coupang context
2026-03-31 20:57:11 +09:00
Jeffrey (Dongkyu) Kim
bff94efe80 Protect README client-support claims from ClawHub regressions
The README already advertises OpenClaw/ClawHub, but the docs
regression only matched OpenClaw. Tighten the assertion to the
exact supported-client fragment so a future edit cannot silently
remove ClawHub while keeping the issue verification command stable.

Constraint: PR #39 already publishes a verification command keyed to the current test name
Rejected: Rename the test to mention ClawHub explicitly | would drift from the published verification command
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep this regression synchronized with the README supported-client line whenever that copy changes
Tested: node --test scripts/skill-docs.test.js --test-name-pattern 'README advertises OpenClaw among the supported coding agents'
Tested: npm run lint
Tested: npm run typecheck
Tested: npm run build
Tested: npm test
Tested: lsp diagnostics for scripts/skill-docs.test.js (0 errors)
Not-tested: N/A
2026-03-31 14:24:54 +09:00
Jeffrey (Dongkyu) Kim
033e8c7379 Document OpenClaw support in the public compatibility list
The approved scope for issue #29 was narrowed to README support messaging,
so this change adds OpenClaw/ClawHub to the supported-client line and locks
that wording with a regression test in the docs suite.

Constraint: Issue #29 was approved as a README-only compatibility/docs change
Rejected: Broader install-doc updates | out of approved scope for this issue
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep OpenClaw support wording aligned with the supported-client README line and its docs regression test
Tested: Focused Node docs regression, npm run lint, npm run typecheck, npm run build, npm test
Not-tested: Live OpenClaw or ClawHub install flow (issue scope was documentation-only)
2026-03-31 14:17:02 +09:00
Jeffrey (Dongkyu) Kim
d62e177a1b Prevent broken Seoul subway proxy defaults before hosted rollout
The Seoul subway proxy endpoint code is present locally, but the hosted public route is not live yet. This change turns the user-facing subway docs back into an explicit proxy configuration flow, replaces the misleading hosted default in setup examples, and keeps subway proxy examples on self-host/local URLs until rollout is verified.

Constraint: Hosted k-skill-proxy.nomadamas.org/v1/seoul-subway/arrival is not live yet
Rejected: Keep the hosted Seoul subway URL as the default path | would send default users to a 404 route
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not restore a hosted Seoul subway default until the public proxy route is deployed and smoke-verified
Tested: node --test scripts/skill-docs.test.js; npm run ci; local proxy smoke on 127.0.0.1:4120 with stubbed Seoul upstream (GET /health, GET /v1/seoul-subway/arrival?stationName=강남)
Not-tested: Live hosted proxy smoke after deployment
2026-03-31 11:18:00 +09:00
Jeffrey (Dongkyu) Kim
fbc004af9d Remove client-side Seoul subway key setup
Route Seoul subway arrival lookups through k-skill-proxy so the
hosted proxy owns the Seoul Open Data upstream key and end users
only need the proxy base URL. Add proxy route coverage, update
skill/docs guidance, and align setup materials with the hosted
proxy flow used for fine dust.

Constraint: Must keep the proxy public, read-only, and dependency-free
Constraint: Must satisfy TDD-first verification and ship on feature/#35 targeting dev
Rejected: Add a separate client helper package | unnecessary extra layer for a single proxy route
Rejected: Keep SEOUL_OPEN_API_KEY as an end-user requirement | defeats the issue goal
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep the Seoul subway proxy surface limited to station-arrival passthrough unless tests/docs expand the contract
Tested: npm run ci; local proxy runtime on 127.0.0.1:4120 for /health and /v1/seoul-subway/arrival on 2026-03-31 with an invalid upstream key
Not-tested: Live success response with a valid Seoul Open API key
Related: #35
2026-03-31 10:25:55 +09:00
Jeffrey (Dongkyu) Kim
ef2c69b81c Replace sops+age encryption with plain dotenv and agent-native credential resolution
Agent environments (OpenClaw, Claude Code, Codex) assume users delegate
credentials to the agent. sops+age added setup friction without real
security benefit since the agent decrypts on every call anyway.

New model: skills declare required env var names; how they are supplied
is up to the agent (own vault, shell env, or ~/.config/k-skill/secrets.env
as the default fallback with 0600 permissions).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:12:04 +09:00
Jeffrey (Dongkyu) Kim
8322f60da0 Keep npm ci green for the toss-securities workspace
The toss-securities workspace was added without a root lockfile entry, so clean installs failed before CI could reach the otherwise-green test suite. This change adds a regression test that pins the required workspace/link metadata and regenerates the root package-lock so npm ci stays reproducible.

Constraint: GitHub Actions runs npm ci before npm run ci
Rejected: Rely on a manual lockfile refresh only | would allow the CI blocker to regress silently
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When adding a workspace, refresh package-lock.json and extend scripts/skill-docs.test.js to pin the required lockfile metadata
Tested: node --test scripts/skill-docs.test.js; npm ci --dry-run; npm run ci; brew tap JungHoonGhae/tossinvest-cli && brew install tossctl && tossctl version; node smoke via packages/toss-securities/src/index.js getQuote('TSLA'); LSP diagnostics on scripts/skill-docs.test.js and packages/toss-securities/src/index.js
Not-tested: No new runtime behavior beyond lockfile metadata refresh
2026-03-30 11:38:00 +09:00
Jeffrey (Dongkyu) Kim
2700e426a9 Add a safe Toss Securities lookup surface without trading mutations
Wrap the upstream tossinvest-cli binary behind a small read-only Node package,
add the matching skill/docs wiring, and lock the behavior with regression tests plus
publish/release metadata so the new workspace stays release-ready.

Constraint: Issue #25 required using JungHoonGhae/tossinvest-cli rather than reimplementing Toss APIs directly
Constraint: The public package surface must stay read-only and avoid wrapping trading mutations
Rejected: Direct HTTP client against unofficial Toss endpoints | issue explicitly required the upstream CLI and would widen maintenance risk
Rejected: Skill docs only with no package wrapper | repo convention is to ship reusable package + docs + release wiring together
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep toss-securities limited to read-only tossctl commands unless a future issue explicitly approves trading flows and adds stronger safeguards
Tested: npm run ci; brew tap JungHoonGhae/tossinvest-cli && brew install tossctl && tossctl version; node smoke calling packages/toss-securities/src/index.js getQuote('TSLA'); lsp diagnostics on affected files
Not-tested: Authenticated account/portfolio/order-history commands against a real Toss session
2026-03-30 11:25:43 +09:00
Jeffrey (Dongkyu) Kim
011aa0e90a Keep the K League feature branch mergeable after dev advanced
Merged dev into feature/#23 and resolved the overlapping root workspace
packaging and skill-doc coverage so the branch now carries both the
new kakao-bar-nearby work from dev and the kleague-results work from
this PR without dropping either surface.

Constraint: Root pack/test wiring must cover every publishable workspace
Rejected: Keep only the PR-side root script/docs updates | would discard newer dev branch coverage for kakao-bar-nearby
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: When adding a new workspace package, update root pack:dry-run coverage and skill-doc regressions in the same change to reduce future merge churn
Tested: npm run ci
Tested: node --input-type=module live smoke for getKLeagueSummary('2026-03-22', { leagueId: 'K리그1', team: 'FC서울', includeStandings: true })
Tested: node --input-type=module live smoke for getMatchResults('2026-03-22', { leagueId: 'K리그2' })
Not-tested: Remote GitHub Actions rerun after pushing the merge-resolution commit
2026-03-29 17:27:06 +09:00
Jeffrey (Dongkyu) Kim
51402dbd29 Keep Kakao smoke docs aligned with verified live output
The station-anchor fixes changed the documented sadang smoke snapshot, so this follow-up pins both published examples to the current 2026-03-29 live result and adds regression coverage to stop the docs from drifting again.

Constraint: Release/package docs must stay aligned with shipped live-smoke evidence
Rejected: Update only the markdown snapshots | would leave no regression guard against future drift
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When live Kakao smoke outputs change, update both the feature doc and package README together and keep the shared doc-regression assertion in sync
Tested: node --test packages/kakao-bar-nearby/test/index.test.js; node --test scripts/skill-docs.test.js; npm ci; npm run ci; live searchNearbyBarsByLocationQuery('사당', { limit: 3, panelLimit: 8 }) on 2026-03-29
Not-tested: Fresh-worktree clone after this doc-only follow-up
2026-03-29 17:05:17 +09:00
Jeffrey (Dongkyu) Kim
83d5f26b39 Add an official K League results client and skill
The K League site already exposes JSON schedule and standings endpoints, so this change wraps those official surfaces in a reusable workspace package and wires the new skill/docs flow into the repo.

The implementation keeps the fetch/parse boundary small, locks normalization with fixtures and regression tests, and documents the publish follow-up needed for the new npm package. Korean-language request headers are pinned so live payloads keep the expected team names and result labels.

Constraint: Must use official K League surfaces instead of adding scraping or third-party dependencies
Rejected: HTML scraping from schedule pages | official JSON endpoints already provide schedule and standings data
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep the accept-language header pinned to Korean unless team alias normalization is expanded for English payloads
Tested: npm run ci; live getKLeagueSummary('2026-03-22', { leagueId: 'K리그1', team: 'FC서울', includeStandings: true }); live getMatchResults('2026-03-22', { leagueId: 'K리그2' })
Not-tested: Live in-progress/postponed match statuses beyond the fixture-covered finished-game path
2026-03-29 15:57:15 +09:00
Jeffrey (Dongkyu) Kim
25b1d3b328 Let agents find open nearby bars from Korean map data
Kakao Map mobile search results and place panels provide enough public data to turn station/neighborhood queries into nearby bar summaries with live open status, menu hints, seating hints, and phone numbers. This adds a reusable workspace package plus docs/skill wiring, while keeping the flow keyless and grounded in TDD + live smoke verification.

Constraint: Must avoid paid/authenticated Kakao APIs and new dependencies
Constraint: Nearby bar results must use current live panel/open-hour data
Rejected: Kakao Local REST API | requires app key/setup and breaks the no-auth posture
Rejected: Naver Map scraping | public responses were more rate-limited in testing
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: If Kakao changes panel3/search HTML contracts, verify headers and anchor-selection heuristics before expanding fallback logic
Tested: node --test packages/kakao-bar-nearby/test/index.test.js
Tested: node --test scripts/skill-docs.test.js
Tested: lsp diagnostics on affected files (0 errors)
Tested: live smoke searchNearbyBarsByLocationQuery('사당') on 2026-03-29
Tested: npm run ci
Not-tested: Precise distance calculation when Kakao station panels omit coordinates
2026-03-29 15:34:31 +09:00
Jeffrey (Dongkyu) Kim
8b36634e28 Stop guessing districts and require exact station retries for ambiguous fine-dust lookups
The fine-dust proxy now resolves natural-language region hints through
city-level station lists and only returns a report when a single station
can be justified. When the hint is ambiguous, the proxy returns a small
candidate list so callers can retry with an exact station name instead
of silently guessing.

The skill guidance was updated to match that runtime contract: region
hint first, then retry with stationName when candidate_stations are
returned. Coordinate-centric guidance was removed from the primary skill
surface so the default path stays lightweight and consistent with the
live proxy behavior.

Constraint: The current AirKorea key can access city-level and station-level measurement APIs but station-info lookups may still return 403
Constraint: Free-API proxy responses must stay safe to expose publicly, so ambiguous locations should not be auto-guessed
Rejected: Auto-pick the first city-level station for unmatched district hints | hides ambiguity and returns misleading air-quality data
Rejected: Keep coordinate-first language in the primary skill | no coordinate source exists in the default user flow
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Preserve the ambiguous_location contract; if you improve matching later, prefer evidence-backed narrowing over silent fallback guesses
Tested: node --test scripts/skill-docs.test.js; npm run test --workspace k-skill-proxy; python3 -m unittest discover -s scripts -p test_fine_dust.py; live curl for ambiguous regionHint=광주 광산구 and exact stationName=우산동(광주)
Not-tested: Broader region alias quality outside the manually checked examples
2026-03-28 23:28:12 +09:00
Jeffrey (Dongkyu) Kim
a3ef6ffac6 Make the fine-dust proxy easier to consume than the upstream APIs
The fine-dust lane now treats the public proxy as the default surface,
keeps a simple summarized report endpoint, and also exposes a narrow
AirKorea passthrough shape so callers can reuse upstream query patterns
without carrying service keys on the client side.

The skill instructions were trimmed down so the default path is obvious,
region-name guidance stays visible, and detailed implementation notes
move into feature docs instead of bloating the primary skill surface.

Constraint: Free-API proxy endpoints are intentionally public and must avoid embedding upstream secrets in the repo
Constraint: AirKorea station-info access can return 403 even when measurement access succeeds, so the report path needs a measurement-only fallback
Rejected: Keep proxy auth via shared token | contradicts the intended public free-API proxy policy
Rejected: Force all callers onto the summary endpoint only | passthrough compatibility is useful for direct HTTP consumers
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep the proxy allowlist narrow; if new upstream routes are exposed, document them explicitly rather than turning this into a generic open proxy
Tested: node --test scripts/skill-docs.test.js; npm run test --workspace k-skill-proxy; python3 -m unittest discover -s scripts -p test_fine_dust.py; live curls against /health, /v1/fine-dust/report, and /B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty
Not-tested: Fresh reboot validation of PM2/cloudflared persistence after the latest code-only changes
2026-03-28 17:14:18 +09:00
Jeffrey (Dongkyu) Kim
a9a59e3655 Keep PR #21 mergeable against the updated dev branch
Merged the latest dev branch into feature/#17 and resolved the overlapping install/test updates by preserving both the fine-dust additions from this branch and the newer Daiso workspace coverage from dev.

Constraint: Base branch dev advanced after PR #21 was opened
Rejected: Rebase and rewrite the feature branch history | a merge update restores mergeability with less risk
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When install docs or regression suites diverge across branches, keep both shipped skill entries and broaden shared assertions instead of dropping one side
Tested: npm run ci
Not-tested: Remote push / GitHub UI mergeability refresh
2026-03-28 09:25:20 +09:00
Jeffrey (Dongkyu) Kim
9ef274c3b7 Honor documented fine-dust fallback semantics
The fine-dust helper still broke the documented station-name path
when the station lookup API returned no rows, and it guessed a
KHAI label from PM10 whenever the upstream API omitted khaiGrade.
This change locks both behaviors with regressions, resolves station
selection to a direct measurement lookup when only the station name
is usable, and reports 정보없음 when the source omits the KHAI field.
The docs now match the implemented fallback and missing-field behavior.

Constraint: Keep the fix compatible with existing fetch_station_payload callers and PR #21 scope
Rejected: Recompute KHAI from other pollutant fields | official formula/data inputs are not implemented in this helper
Rejected: Fail hard when station lookup is empty despite --station-name | contradicts the documented direct station-name fallback
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not synthesize 통합대기등급 from PM10/PM2.5 surrogates unless the official KHAI formula and inputs are implemented end-to-end
Tested: python3 scripts/test_fine_dust.py; npm run ci; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --lat 37.5665 --lon 126.9780; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --region-hint '서울 강남구'; python3 scripts/fine_dust.py --help; env -u AIR_KOREA_OPEN_API_KEY python3 scripts/fine_dust.py report --lat 37.5665 --lon 126.9780; python3 -m py_compile scripts/fine_dust.py scripts/test_fine_dust.py
Not-tested: Live Air Korea API responses with a real service key
2026-03-27 22:58:01 +09:00
Jeffrey (Dongkyu) Kim
1e13cc10e1 Keep PR #19 CI stable without user Python site-packages
The validate job was failing because the KTX helper regression suite imported optional runtime dependencies directly from the module top level. GitHub Actions does not inherit the local user site-packages that made those imports succeed on the workstation, so the test suite died before it could exercise the helper logic.

This change makes the helper import-safe in minimal environments by deferring requests usage, providing lightweight fallbacks for optional Korail/Crypto imports during unit tests, and surfacing an explicit install command when the real runtime dependencies are actually needed. The docs now list pycryptodome alongside korail2, and the regression suite forces PYTHONNOUSERSITE=1 so CI keeps exercising the dependency-light path instead of accidentally relying on a developer machine.

Constraint: PR #19 must keep npm run ci green on GitHub Actions without assuming user-level Python packages
Constraint: The KTX helper still needs the real korail2 and pycryptodome packages for live reservation flows
Rejected: Installing ad-hoc Python packages in the CI workflow | hides the import-safety regression instead of fixing the helper/test contract
Rejected: Removing the Python regression suite from skill-docs coverage | would lose the guard on the train_id reservation flow
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep the KTX helper importable under PYTHONNOUSERSITE=1 and document every required runtime package in both the skill and install docs
Tested: PYTHONNOUSERSITE=1 python3 -m unittest discover -s scripts -p test_ktx_booking.py
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Not-tested: GitHub Actions validate rerun after push
2026-03-27 22:51:33 +09:00
Jeffrey (Dongkyu) Kim
3237d9dc2f Report fallback provenance honestly after nearby lookup misses
The CLI previously inferred lookup provenance only from whether lat/lon
were supplied, which overstated precision when the Air Korea nearby
station lookup returned no rows and the command had to fall back to the
region/station search path. Carry the resolved lookup source through the
station-fetch step so rendered reports distinguish true coordinate hits
from fallback results, and lock that behavior with a JSON CLI regression.

Constraint: Keep the existing fetch_station_payload interface stable for current tests and callers
Rejected: Recompute provenance inside build_report from args alone | cannot observe live nearby-empty fallback outcome
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If station lookup adds more branches, keep report provenance wired from the resolved fetch path rather than inferring from raw inputs
Tested: PYTHONPATH=scripts python3 -m unittest scripts.test_fine_dust.FineDustTests.test_cli_json_report_marks_region_fallback_when_nearby_lookup_is_empty; python3 scripts/test_fine_dust.py; npm run ci; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --lat 37.5665 --lon 126.9780; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --region-hint '서울 강남구'; python3 scripts/fine_dust.py --help; env -u AIR_KOREA_OPEN_API_KEY python3 scripts/fine_dust.py report --lat 37.5665 --lon 126.9780
Not-tested: Live Air Korea network responses with a real API key in this environment
2026-03-27 22:44:04 +09:00
Jeffrey (Dongkyu) Kim
1453448947 Honor Air Korea's TM-coordinate contract for nearby station lookup
PR #21 review found the live location path was sending raw WGS84 latitude/longitude into getNearbyMsrstnList. This updates the helper to convert WGS84 inputs into Air Korea's central-origin TM coordinates without adding a new dependency, adds regression coverage for the live request path plus fallback behavior, and aligns the published skill/docs examples with tmX/tmY usage.

Constraint: Air Korea nearby-station lookup requires TM coordinates and this repo should not add new runtime dependencies for a helper script
Rejected: Add pyproj/proj4 as a dependency | unnecessary dependency footprint for a deterministic coordinate transform
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep getNearbyMsrstnList on TM inputs only; if the upstream coordinate contract changes, verify against the official Air Korea docs before editing request params again
Tested: npm run ci; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --lat 37.5665 --lon 126.9780; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --region-hint '서울 강남구'; python3 scripts/fine_dust.py --help; env -u AIR_KOREA_OPEN_API_KEY python3 scripts/fine_dust.py report --lat 37.5665 --lon 126.9780; python3 -m py_compile scripts/fine_dust.py scripts/test_fine_dust.py
Not-tested: Live Air Korea API call with a real service key on this branch
2026-03-27 22:28:24 +09:00
Jeffrey (Dongkyu) Kim
326a707cb6 Keep PR #19 mergeable while preserving both npm package releases
Merged origin/dev into feature/#15 and resolved the shared docs, package script, and skill regression conflicts so the Daiso work and the Blue Ribbon work can ship together. The resolution keeps both publishable workspaces in the dry-run packaging check and aligns install/source docs plus regression coverage with the combined branch state.

Constraint: PR #19 targets dev and GitHub marked it CONFLICTING against origin/dev
Constraint: Release and packaging changes must continue to pass npm run ci after conflict resolution
Rejected: Dropping the Blue Ribbon additions during merge resolution | would lose newer dev branch work
Rejected: Keeping only one workspace in pack:dry-run | would leave the other publishable package unverified
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If another publishable workspace is added, extend both package.json pack:dry-run and scripts/skill-docs.test.js together
Tested: npm install; npm run ci
Not-tested: GitHub mergeability refresh after push
2026-03-27 22:19:48 +09:00
Jeffrey (Dongkyu) Kim
8c86d54b1f Add local air-quality lookup so k-skill covers location-based dust checks
Issue #17 approved an Air Korea two-API flow with a region fallback, so this change adds a new fine-dust skill, wires it into the repo docs/setup surfaces, and includes a runnable helper plus fixtures/tests for repeatable verification.

Constraint: Must use the approved official Air Korea APIs and secure secret registration flow
Rejected: Use an unofficial air-quality API | issue follow-up explicitly approved the Air Korea two-API flow
Rejected: Require coordinates only | issue discussion required a practical fallback when precise location is unavailable
Confidence: high
Scope-risk: moderate
Directive: Keep the helper and docs aligned with Air Korea endpoint names and fallback order if the official API contract changes
Tested: npm run ci; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --lat 37.5665 --lon 126.9780; python3 scripts/fine_dust.py report --station-file scripts/fixtures/fine-dust-stations.json --measurement-file scripts/fixtures/fine-dust-measurements.json --region-hint '서울 강남구'; python3 scripts/fine_dust.py --help; missing-secret error path without AIR_KOREA_OPEN_API_KEY
Not-tested: Live Air Korea API calls with a real AIR_KOREA_OPEN_API_KEY
2026-03-27 22:06:19 +09:00
Jeffrey (Dongkyu) Kim
6cff0df3d0 Keep Blue Ribbon package docs aligned with the shipped nearby flow
Add a regression that pins the package README to the location-first guidance, 코엑스 alias example, and official Blue Ribbon surfaces, then document the search/zone and restaurants/map flow in the package README so the reusable workspace package stays aligned with the shipped skill behavior.

Constraint: Follow-up is scoped to issue #16 / PR #18 and must stay within approved docs and regression coverage
Rejected: Leave package README coverage implicit in the skill and feature docs tests | package docs could drift unnoticed
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep packages/blue-ribbon-nearby/README.md aligned with blue-ribbon-nearby/SKILL.md and docs/features/blue-ribbon-nearby.md when official surfaces or landmark aliases change
Tested: node --test scripts/skill-docs.test.js (failed first, then passed); node --test packages/blue-ribbon-nearby/test/index.test.js scripts/skill-docs.test.js; npm ci; npm run ci; live smoke searchNearbyByLocationQuery('광화문', { distanceMeters: 1000, limit: 5 }); live smoke searchNearbyByLocationQuery('코엑스', { distanceMeters: 1000, limit: 5 })
Not-tested: Separate publish automation beyond npm run ci pack:dry-run
2026-03-27 19:58:16 +09:00
Jeffrey (Dongkyu) Kim
2352856826 Enable official Daiso store stock lookups before visiting a branch
Added a new Daiso skill and reusable workspace package around the
official Daiso Mall store search, product search, and pickup-stock
surfaces. The implementation stays stock-first because the official
surface clearly exposes store inventory but I could not verify any
official aisle/location endpoint for in-store placement.

Constraint: Must rely on official Daiso Mall surfaces before considering scraping
Constraint: Tests-first implementation and full repo CI must stay green
Rejected: Playwright-first scraping flow | official SearchGoods and selStrPkupStck endpoints were sufficient
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If Daiso exposes an official in-store location endpoint later, extend this package instead of inferring shelf locations
Tested: node --test scripts/skill-docs.test.js
Tested: node --test packages/daiso-product-search/test/index.test.js
Tested: npm test
Tested: npm run ci
Tested: live smoke for searchStores/searchProducts/getStorePickupStock/lookupStoreProductAvailability against Daiso Mall on 2026-03-27
Not-tested: Logged-in-only variants beyond anonymous official search/store/stock surfaces
2026-03-27 18:53:53 +09:00
Jeffrey (Dongkyu) Kim
4121e086eb Make nearby Blue Ribbon searches reusable and location-first
Issue #16 adds a new location-first Blue Ribbon skill, documents that 맛집 requests should route here by default, and ships a reusable npm workspace client over the official Blue Ribbon zone/search surfaces.

The package now parses official zone links, matches user-provided location text or coordinates, and queries the nearby JSON endpoint while filtering to certified ribbon venues only. Repo docs, install guidance, release metadata, and regression coverage were updated together so the new skill can ship cleanly.

Constraint: Must ask the user for current location before nearby search
Constraint: Blue Ribbon nearby calls require browser-like headers and official zone/search parameters
Rejected: Auto-detect user geolocation | violates the issue requirement to ask first
Rejected: Generic web search scraping without a reusable package | weaker reuse and less aligned with official Blue Ribbon surfaces
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep certified-ribbon filtering pinned to RIBBON_ONE/TWO/THREE unless the official Blue Ribbon contract changes
Tested: npm run ci; live smoke with searchNearbyByLocationQuery('광화문', { distanceMeters: 1000, limit: 5 })
Not-tested: Ambiguous location strings that require conversational disambiguation beyond current zone heuristics
2026-03-27 18:20:05 +09:00
Jeffrey (Dongkyu) Kim
6c2c0d54e3 Keep waiting-list reservations aligned with the selected train
The reserve replay search now auto-includes waiting-list candidates when users opt into --try-waiting, so the stable train_id chosen from search remains resolvable for docs-following flows. A regression test reproduces the prior stale-train failure and locks the corrected behavior.\n\nConstraint: Reserve must keep using the existing train_id replay flow without broad CLI redesign\nRejected: Require users to repeat --include-waiting-list on reserve | contradicts the documented flow and review feedback\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: Keep --try-waiting and reserve replay search semantics aligned so waiting-list-only trains remain selectable\nTested: python3 -m py_compile scripts/ktx_booking.py; python3 -m unittest discover -s scripts -p test_ktx_booking.py; node --test scripts/skill-docs.test.js; npm run ci; python3 scripts/ktx_booking.py --help; python3 scripts/ktx_booking.py reserve --help; live search/reservations/reserve/cancel/reservations via sops-managed Korail credentials\nNot-tested: Live waiting-list reservation creation (no waiting-list-eligible train appeared in the smoke search output)
2026-03-27 11:26:38 +09:00
Jeffrey (Dongkyu) Kim
04653f761f Prevent KTX reserve retries from drifting to the wrong train
Reserve used to replay search results and trust a fresh ordinal index, which could silently target a different train when sold-out entries disappeared or ordering changed. This change emits a stable train_id from search output, requires reserve to match the exact train identity on replay, and updates docs/tests to lock the safer CLI contract.

Constraint: Korail search results can reorder between search and reserve while the helper still needs to replay the live lookup
Rejected: Keep --train-index as the reserve selector | still allows silent wrong-train bookings when the result set shifts
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If upstream train identity fields change, update the train_id payload and the docs/tests together before changing reserve selection again
Tested: python3 -m py_compile scripts/ktx_booking.py; python3 -m unittest discover -s scripts -p test_ktx_booking.py; node --test scripts/skill-docs.test.js; npm run ci; live search/reservations/reserve/cancel/reservations with sops-managed Korail credentials
Not-tested: Forced live stale-train_id failure against a disappearing train between search and reserve
2026-03-27 11:09:14 +09:00
Jeffrey (Dongkyu) Kim
1a74a74734 Keep the KTX helper docs aligned with the live CLI contract
The feature branch already restored the patched Korail helper, so this follow-up stays narrow: lock the documented helper flags in regression tests and teach both KTX docs surfaces about the search and waiting-list toggles the live CLI already supports.

Constraint: Follow-up had to stay compatible with the shipped scripts/ktx_booking.py parser and existing PR scope
Rejected: Expand README into a full command matrix | duplicates the dedicated KTX docs and skill guide
Confidence: high
Scope-risk: narrow
Directive: When the helper CLI changes, update both KTX docs surfaces and the regression assertions in the same change
Tested: node --test scripts/skill-docs.test.js
Tested: python3 -m py_compile scripts/ktx_booking.py
Tested: npm run ci
Tested: live python3 scripts/ktx_booking.py search/reservations/reserve/cancel via sops-managed Korail credentials
Not-tested: 예약대기 success path on a sold-out train
2026-03-27 10:46:19 +09:00
Jeffrey (Dongkyu) Kim
3f59d1518b Restore live KTX booking flow against Korail's new anti-bot checks
Korail's current mobile endpoints reject the published raw korail2
examples with MACRO ERROR, so this change adds a repo-local
helper that patches Dynapath token/Sid/version behavior and reroutes
KTX docs/tests to the helper-based flow.

Constraint: Must keep credentials in sops-managed secrets and prove the flow with a real reservation
Rejected: Fork and publish a patched korail2 package | broader release surface than this repo needs
Confidence: high
Scope-risk: moderate
Directive: Re-check the helper constants and private korail2 hooks whenever Korail changes its mobile anti-bot flow
Tested: python3 -m py_compile scripts/ktx_booking.py
Tested: npm run ci
Tested: Live search via scripts/ktx_booking.py search 서울 부산 20260328 000000 --include-no-seats --include-waiting-list
Tested: Live reserve/cancel via scripts/ktx_booking.py reserve/cancel/reservations on March 28, 2026 KTX #001
Not-tested: Final payment completion after reservation
2026-03-27 10:33:16 +09:00
Jeffrey (Dongkyu) Kim
42c753a985 Prevent delivery doc sample formatting drift
The delivery-tracking regression already pinned parsed CJ/ePost values to checked-in fixtures, but it still allowed the published JSON fence text to drift in key order or formatting while preserving the same parsed objects. This follow-up extracts the raw fenced JSON once, keeps parsing layered on top, and asserts both docs match the fixture's pretty-printed text byte-for-byte.

Constraint: CI must keep using checked-in fixtures instead of live network calls
Constraint: Follow-up should stay scoped to scripts/skill-docs.test.js
Rejected: Duplicate four separate string assertions | nested loops keep the carrier/doc matrix compact with the same coverage
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep delivery-tracking sample JSON blocks sourced from the checked-in fixture text before relaxing formatting assertions
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: python3 /tmp/cj_verify.py
Tested: npx --yes skills add . --list
Not-tested: python3 /tmp/epost_verify.py | service.epost.go.kr timed out with curl exit 28 on 2026-03-27
2026-03-27 04:18:44 +09:00
Jeffrey (Dongkyu) Kim
55542d2f0a Keep delivery doc provenance tied to verified smoke tests
The sample payload fixture already pins the published JSON bodies, but the dated provenance lines remained free text. This adds a tiny checked-in provenance fixture and a regression that requires both delivery-tracking docs to keep the verified date/invoice sentence immediately adjacent to each sample JSON block.

Constraint: Keep the docs regression offline and fixture-backed without adding live network calls to CI
Rejected: Inlining the expected date/invoice literals in the test | harder to keep the docs provenance contract explicit and reusable
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Update the provenance fixture whenever the published smoke-test date or invoice examples change
Tested: node --test scripts/skill-docs.test.js; npm run ci; python3 /tmp/cj_verify.py; npx --yes skills add . --list; architect verification
Not-tested: python3 /tmp/epost_verify.py (service.epost.go.kr timed out with curl exit 28 from this environment)
2026-03-27 04:02:14 +09:00
Jeffrey (Dongkyu) Kim
cfa76eccf3 Pin delivery-tracking doc samples to checked fixtures
The review follow-up showed the docs regression only proved that the two
markdown copies matched each other. This change adds a checked-in fixture
for the verified CJ and 우체국 public outputs, then requires both docs to
match that fixture exactly while scanning the full parsed samples for TEL,
phone-like strings, and raw sensitive field names.

Constraint: Must keep CI offline while tying docs to verified smoke-test invoices
Constraint: Existing PR #13 already publishes dated CJ and 우체국 public samples
Rejected: Keep shape-only assertions | shared-but-wrong markdown drift would still pass CI
Confidence: high
Scope-risk: narrow
Directive: Refresh scripts/fixtures/delivery-tracking-public-samples.json only after rerunning live smoke verification for the documented invoices
Tested: node --test scripts/skill-docs.test.js; npm run ci; python3 /tmp/cj_verify.py; npx --yes skills add . --list
Not-tested: python3 /tmp/epost_verify.py (service.epost.go.kr connection timed out repeatedly on 2026-03-27 from this environment)
2026-03-27 03:39:31 +09:00
Jeffrey (Dongkyu) Kim
21f036e942 Document the verified public tracking outputs explicitly
Add aligned CJ and 우체국 sample public-output blocks to both delivery-tracking docs and extend the docs regression so those examples stay synchronized with the normalized non-PII contract. The new examples are dated live smoke-test captures, giving reviewers and users a concrete expected result without relying on raw carrier fields.

Constraint: feature/#4 already matched dev, so the follow-up needed a small reviewable change to reopen PR work on the same branch
Constraint: Keep verification offline in CI and avoid new runtime dependencies
Rejected: Add live carrier calls to CI | external endpoints are flaky and would make the docs regression nondeterministic
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Refresh both dated sample-output blocks together if the smoke-test invoices ever change their public tracking history
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: python3 /tmp/cj_verify.py
Tested: python3 /tmp/epost_verify.py
Tested: npx --yes skills add . --list
Tested: git diff --check
Not-tested: Automated live carrier verification in CI
2026-03-27 02:44:48 +09:00
Jeffrey (Dongkyu) Kim
fed0973979 Pin the delivery examples to exact schema mappings
The current delivery-tracking follow-up already describes a shared
normalized schema, but the regression test still allowed drift in the
actual field expressions. This change upgrades the docs regression to
exact key/value allowlists and aligns the 우체국 feature example with
named summary groups so the published examples stay in sync.

Constraint: Follow-up had to stay docs-first on feature/#4 / PR #12
Constraint: The published CJ and 우체국 examples must remain privacy-safe while sharing one exact schema contract
Rejected: Keep key-only checks in the regression suite | still allows silent expression drift in published examples
Rejected: Refactor the docs examples into separate reusable scripts | too broad for this bounded follow-up
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If the delivery examples change again, update both the printed object mappings and the exact allowlist regression in the same diff
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Not-tested: Live carrier requests were not needed for this schema-lock follow-up because behavior remained documentation-only and prior live verification already covered the transport paths
2026-03-27 02:06:27 +09:00
Jeffrey (Dongkyu) Kim
47cdc09b4a Prevent delivery doc schema drift from reintroducing extra public fields
Tighten the delivery-tracking docs regression so it parses the published
CJ and 우체국 normalized JSON examples and compares them against exact
allowlisted key sets for both the top-level object and each recent-events
entry. This closes the prior presence-only gap without expanding the
follow-up beyond the docs verification surface.

Constraint: Follow-up scope is limited to scripts/skill-docs.test.js and the existing PR #11 branch
Rejected: Add more denylist regexes only | still leaves room for renamed PII-bearing keys to slip into published examples
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep any future published delivery example changes aligned with these exact top-level and recent_events allowlists before widening the public contract
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: python3 normalized CJ official endpoint verification for 1234567890
Tested: python3 우체국 follow-up verification for 1234567890123
Not-tested: No mutated negative fixture was added beyond the published examples already checked by the regression suite
2026-03-27 01:55:51 +09:00
Jeffrey (Dongkyu) Kim
448b008522 Clarify the shared delivery output contract in published docs
The approved issue-4 follow-up was already on the branch, so this pass tightened the regression suite first and then made the shared schema explicit in both delivery-tracking docs. The docs now name the normalized keys directly and state that recent_events is capped at the latest three entries, matching the verified CJ and 우체국 examples.

Constraint: Keep the published examples aligned with the verified carrier flows and the existing normalized output contract

Rejected: Broader refactor of the delivery-tracking examples | unnecessary for this follow-up and would widen review scope

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep the docs and regression test aligned whenever the normalized tracking schema changes

Tested: node --test scripts/skill-docs.test.js

Tested: npm run ci

Tested: npx --yes skills add . --list

Tested: Live CJ official flow for 1234567890

Tested: Live 우체국 flow for 1234567890123
2026-03-27 01:29:32 +09:00
Jeffrey (Dongkyu) Kim
65e203a005 Normalize published delivery outputs to one shared contract
The delivery-tracking docs promised one carrier-agnostic result shape,
but the CJ and 우체국 examples had drifted into different schemas.
This updates both published examples and the regression suite to emit
the same normalized fields, include recent_events, and sanitize ePost
TEL fragments observed during live verification.

Constraint: Issue #4 follow-up must keep published examples non-PII and aligned with the documented common-format contract
Rejected: Preserve carrier-specific fields in the published examples | contradicts the carrier-adapter normalization promise and review feedback
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep CJ and ePost published examples on the same normalized schema and strip contact fragments from documented ePost locations
Tested: node --test scripts/skill-docs.test.js; npm run ci; npx --yes skills add . --list; live CJ verification for 1234567890; live ePost verification for 1234567890123; architect verification
Not-tested: Shared runtime adapter implementation outside the published docs/examples
2026-03-27 01:29:32 +09:00
Jeffrey (Dongkyu) Kim
5b104d27e2 Protect published tracking examples from leaking carrier contact data
The CJ official response can embed staff name and phone data in crgNm, so the published skill and feature examples now emit only normalized summary fields. The root docs regression suite also locks the safe output shape so raw CJ event payloads do not creep back into the docs.\n\nConstraint: Official CJ tracking responses may include personal contact data in crgNm\nRejected: Keep a message field with ad-hoc redaction | deleting the field is safer for published examples\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: Keep carrier doc examples limited to normalized summary fields; do not dump raw tracking payloads without privacy review\nTested: node --test scripts/skill-docs.test.js; npx --yes skills add . --list; npm run ci; CJ official curl+cookie+_csrf verification for 1234567890; 우체국 curl --http1.1 --tls-max 1.2 verification for 1234567890123; lsp_diagnostics scripts/skill-docs.test.js\nNot-tested: Live carrier responses beyond the documented smoke-test invoice numbers
2026-03-27 01:29:32 +09:00
Jeffrey (Dongkyu) Kim
e257ab39a0 Avoid leaking CJ contact details in published tracking examples
The first delivery-tracking draft exposed too much of the raw CJ event payload in the public examples. This follow-up keeps the examples useful for status checks while normalizing them to non-PII fields only, and locks that expectation in the docs regression suite so the raw  field is not reintroduced.

Constraint: Must preserve the verified official CJ flow while removing avoidable personal-contact leakage from the shipped examples
Constraint: Follow-up had to stay docs-first and scoped to the existing feature/#4 PR branch
Rejected: Keep raw CJ payload output and rely on users to ignore  | published examples should not leak names/phone numbers unnecessarily
Rejected: Drop CJ example detail entirely | loses practical verification value for the main carrier path
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any future CJ example update must continue to avoid printing raw  or other contact-bearing fields in public docs
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: python3 normalized CJ official endpoint verification for 1234567890
Tested: python3 우체국 follow-up verification for 1234567890123
Not-tested: Real non-placeholder customer waybills with different event shapes
2026-03-27 00:48:02 +09:00
Jeffrey (Dongkyu) Kim
4a4ab95541 Make official parcel tracking available without aggregator services
Issue #4 asks for a first-class way to check Korean parcel status from invoice numbers. This change adds a delivery-tracking skill covering CJ대한통운 and 우체국 through their official surfaces, wires it into the repo docs, and locks the carrier-specific endpoint rules with the root regression suite.

Constraint: Must stay docs-first with no new dependencies or bundled carrier client code
Constraint: Official carrier surfaces use different transport shapes (CJ JSON with _csrf, 우체국 HTML/form flow) so the skill must document adapter-specific rules explicitly
Rejected: Use a third-party aggregate tracking site | violates official-surface requirement and weakens long-term maintainability
Rejected: Collapse both carriers into one generic parsing recipe | carrier-specific transport and parsing rules differ too much
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep future carrier additions as explicit carrier adapters with official URLs, length rules, and parsing guidance instead of broadening the current CJ/우체국 snippets into a catch-all flow
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: npx --yes skills add . --list
Tested: python3 CJ official endpoint verification for 1234567890 and 000000000000
Tested: python3 requests verification of the 우체국 landing page plus trace.RetrieveDomRigiTraceList.comm follow-up for 1234567890123
Not-tested: Real customer shipment numbers across more carriers or edge-case invoice formats
2026-03-27 00:30:09 +09:00
Jeffrey (Dongkyu) Kim
ca490a5e6e Harden postcode lookup guidance for flaky shell/runtime conditions
The zipcode-search docs were directionally correct, but they left a few practical failure modes underexplained for real operator use. This update makes the retry order explicit, adds guidance for temp-file based parsing in wrapped shells, and documents the benign curl (23) case when downstream readers close early.

Constraint: Keep the change docs-first without adding runtime code or dependencies
Constraint: The official ePost endpoint remains intermittently flaky, so guidance must focus on stable operator behavior rather than pretending transport is deterministic
Rejected: Replace the docs example with a larger shell wrapper script | too heavy for a small skill-doc improvement
Rejected: Ignore curl (23) and here-doc issues as user error | repeated operator confusion is worth documenting
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If the zipcode-search example changes again, keep the retry order and shell-wrapper caveats aligned between the skill doc, feature doc, and regression test
Tested: node --check scripts/skill-docs.test.js
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: npx --yes skills add . --list
Not-tested: Live ePost requests for this doc-only follow-up
2026-03-26 23:58:01 +09:00
Jeffrey (Dongkyu) Kim
c4f9a32c51 Make postcode lookup available as a first-class k-skill
Issue #3 asks for a low-friction way to turn a known Korean address into a postal code. This change adds a dedicated zipcode-search skill, wires it into repo docs, and protects the new discovery/documentation surface with a root-level regression test that now runs under npm test/ci.

Constraint: Must use the official ePost postal search page and avoid new dependencies
Rejected: Data.go.kr key-based postal API | unnecessary setup for a simple lookup skill
Confidence: high
Scope-risk: narrow
Directive: Keep the zipcode-search extraction logic aligned with the official ePost HTML fields unless a more stable public API replaces it
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: npx --yes skills add . --list
Tested: python3 live query against the ePost endpoint for 세종대로 209
Not-tested: Broader address variants beyond the verified ePost query example
2026-03-26 23:15:54 +09:00
Jeffrey (Dongkyu) Kim
fbc44b795b Document safe macOS KakaoTalk skill usage
Add the new kakaotalk-mac skill as a docs-first capability with regression coverage, repository discoverability, and clear macOS permission/install guidance built around kakaocli. The change keeps the repo docs-only while making the feature installable and reviewable through existing skill validation paths.

Constraint: This repo ships skill definitions and docs, not KakaoTalk automation binaries
Constraint: Guidance must stay macOS-specific and require explicit confirmation before sending to other people
Rejected: Add executable integration code in this repo | issue scope is docs-only skill packaging
Rejected: Document unofficial non-macOS workarounds | upstream tool is macOS-only and issue explicitly targets Mac
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep future updates aligned with upstream kakaocli commands and macOS permission requirements before broadening this skill
Tested: node --test scripts/skill-docs.test.js
Tested: npm run ci
Tested: npx --yes skills add . --list
Tested: Architect review approval on working tree
Not-tested: Live kakaocli execution against a local KakaoTalk installation on macOS
2026-03-26 23:12:42 +09:00
Jeffrey (Dongkyu) Kim
60eef129db Keep HWP image-file fallback guidance aligned across docs
The approved HWP doc fix was already present on feature/#1, but the
skill-level guidance still lacked the verified `--images-dir` fallback
that the feature guide documented for separate image files. Add a
regression first to lock that expectation, then mirror the CLI-backed
fallback in `hwp/SKILL.md` so future edits cannot drift.

Constraint: Follow-up had to stay on PR #5 / branch `feature/#1` and remain documentation-only
Constraint: `hwpjs to-markdown --help` is the source of truth for `--include-images` and `--images-dir`
Rejected: Leave the fallback only in `docs/features/hwp.md` | the skill doc would still diverge from the verified workflow
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep `hwp/SKILL.md`, `docs/features/hwp.md`, and `scripts/skill-docs.test.js` aligned with the live `hwpjs to-markdown --help` surface
Tested: node --test scripts/skill-docs.test.js
Tested: npx --yes @ohah/hwpjs to-markdown --help
Tested: npm test
Tested: npm run ci
Tested: npx --yes skills add . --list
Not-tested: End-to-end conversion against a real `.hwp` fixture in this repository
2026-03-26 13:10:52 +09:00
Jeffrey (Dongkyu) Kim
48b8d8153e Clarify HWP markdown verification in the feature guide
The feature guide already documented `--include-images`, but it did not
spell out the verification rule as clearly as the skill doc. Add a
feature-level verification checklist and tighten the regression test so
repo docs stay aligned with the actual `hwpjs` inline-image behavior.

Constraint: `hwpjs to-markdown --include-images` embeds images as base64 data URIs instead of writing sidecar files
Rejected: Leave verification guidance only in `hwp/SKILL.md` | feature docs could drift without their own regression coverage
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep the feature-guide verification text aligned with `npx --yes @ohah/hwpjs to-markdown --help` if the CLI flag behavior changes
Tested: node --test scripts/skill-docs.test.js; npx --yes @ohah/hwpjs to-markdown --help; npm test; npm run ci; npx --yes skills add . --list
Not-tested: End-to-end conversion against a real `.hwp` fixture
2026-03-26 12:34:34 +09:00