[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C1SVBVX42MNQ52TVXF9FAC":3,"skill-same:01M6C1SVBVX42MNQ52TVXF9FAC":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":53,"ownerHtmlUrl":54,"ownerBlogUrl":55,"ownerDescription":56,"updatedAt":57,"install":58,"resources":71},"01M6C1SVBVX42MNQ52TVXF9FAC","archive-acquisition",null,"Patterns for acquiring content from Internet Archive and archival sources","jmagly\u002Faiwg","jmagly","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1159087?v=4","01M6C10AK8N2WCSQN11FYGTJWN","Joseph Magly","01M6C10AQ8A2RMED1Y1BSVY7NF",229,"MIT","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Farchive-acquisition\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38],"archive","acquisition","archive acquisition","content","Media","patterns","sources","archival","internet","for","2026-11-10 10:12:30",false,"---\nnamespace: aiwg\nplatforms: [all]\nname: archive-acquisition\ndescription: Patterns for acquiring content from Internet Archive and archival sources\ncategory: media-curator\n---\n\n# Archive Acquisition Skill\n\nSpecialized patterns and techniques for acquiring media content from Internet Archive (archive.org) and other archival sources. Focuses on bulk downloads, quality selection, format filtering, and collection management.\n\n## Internet Archive Overview\n\nInternet Archive hosts massive collections of audio, video, text, and software. Key characteristics:\n\n- **Open access**: Most content freely downloadable\n- **Multiple formats**: Same item often available in FLAC, MP3, OGG, etc.\n- **Collections**: Items grouped by uploader, topic, or curator\n- **Metadata**: Rich JSON metadata for every item\n- **API access**: Full programmatic access via REST API\n\n## Discovery Patterns\n\n### Search API\n\nFind items matching specific criteria:\n\n```bash\n# Search for items by keyword and mediatype\nsearch_archive() {\n  local query=\"$1\"\n  local mediatype=\"$2\"  # audio, movies, texts, etc.\n  local rows=\"${3:-100}\"  # Results per page\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=$query AND mediatype:$mediatype\" \\\n    -d \"fl[]=identifier,title,creator,date,format\" \\\n    -d \"rows=$rows\" \\\n    -d \"output=json\" \\\n    | jq '.response.docs[]'\n}\n\n# Example: Search for Grateful Dead concerts\nsearch_archive \"grateful dead\" \"audio\" 50\n```\n\n### Response Format\n\n```json\n{\n  \"identifier\": \"gd1977-05-08.sbd.miller.97065.flac16\",\n  \"title\": \"Grateful Dead Live at Barton Hall on 1977-05-08\",\n  \"creator\": \"Grateful Dead\",\n  \"date\": \"1977-05-08\",\n  \"format\": [\"Flac\", \"VBR MP3\", \"Ogg Vorbis\", \"Metadata\"]\n}\n```\n\n### Collection Browsing\n\nList all items in a collection:\n\n```bash\n# Get items from a specific collection\nget_collection_items() {\n  local collection=\"$1\"\n  local rows=\"${2:-1000}\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=collection:$collection\" \\\n    -d \"fl[]=identifier,title,format\" \\\n    -d \"rows=$rows\" \\\n    -d \"output=json\" \\\n    | jq -r '.response.docs[] | .identifier'\n}\n\n# Example: Get all items from GratefulDead collection\nget_collection_items \"GratefulDead\" 500\n```\n\n### Advanced Query Patterns\n\n```bash\n# Find items by date range\nsearch_by_date() {\n  local creator=\"$1\"\n  local start_date=\"$2\"  # YYYY-MM-DD\n  local end_date=\"$3\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=creator:\\\"$creator\\\" AND date:[$start_date TO $end_date]\" \\\n    -d \"fl[]=identifier,title,date\" \\\n    -d \"rows=100\" \\\n    -d \"output=json\" \\\n    | jq '.response.docs[]'\n}\n\n# Find items with specific format available\nsearch_by_format() {\n  local query=\"$1\"\n  local format=\"$2\"  # FLAC, MP3, etc.\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=$query AND format:$format\" \\\n    -d \"fl[]=identifier,title,format\" \\\n    -d \"rows=100\" \\\n    -d \"output=json\" \\\n    | jq '.response.docs[]'\n}\n\n# Example: Find all FLAC recordings of specific artist\nsearch_by_format \"pink floyd\" \"Flac\"\n```\n\n## Item Metadata Retrieval\n\n### Get Item Details\n\n```bash\n# Retrieve full metadata for an item\nget_item_metadata() {\n  local identifier=\"$1\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq '.'\n}\n\n# Extract specific metadata fields\nget_item_files() {\n  local identifier=\"$1\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format != \"Metadata\") | \"\\(.name)\\t\\(.format)\\t\\(.size)\"'\n}\n\n# Example output:\n# gd77-05-08d1t01.flac    Flac    45123456\n# gd77-05-08d1t01.mp3     VBR MP3 12345678\n```\n\n### Filter by Format\n\n```bash\n# Get only FLAC files from an item\nget_flac_files() {\n  local identifier=\"$1\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format == \"Flac\") | .name'\n}\n\n# Get best quality audio files (prefer FLAC, fallback to 320K MP3)\nget_best_audio_files() {\n  local identifier=\"$1\"\n\n  # Try FLAC first\n  local flac_files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format == \"Flac\") | .name')\n\n  if [[ -n \"$flac_files\" ]]; then\n    echo \"$flac_files\"\n    return 0\n  fi\n\n  # Fallback to highest bitrate MP3\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format == \"VBR MP3\" or .format == \"320Kbps MP3\") | .name'\n}\n```\n\n## Download Patterns\n\n### Single Item Download\n\n```bash\n# Download all files from a single item\ndownload_item() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format_filter=\"$3\"  # Optional: FLAC, MP3, etc.\n\n  mkdir -p \"$output_dir\"\n\n  # Get file list\n  local files\n  if [[ -n \"$format_filter\" ]]; then\n    files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n      | jq -r \".files[] | select(.format == \\\"$format_filter\\\") | .name\")\n  else\n    files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n      | jq -r '.files[] | select(.format != \"Metadata\") | .name')\n  fi\n\n  # Download each file\n  while IFS= read -r file; do\n    echo \"Downloading: $file\"\n    wget -q --show-progress \\\n      \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F$file\" \\\n      -P \"$output_dir\"\n  done \u003C\u003C\u003C \"$files\"\n}\n\n# Example: Download all FLAC files from an item\ndownload_item \"gd1977-05-08.sbd.miller.97065.flac16\" \"\u002Fmnt\u002Farchive\u002Fgrateful-dead\u002F1977-05-08\" \"Flac\"\n```\n\n### Recursive Collection Download\n\n```bash\n# Download entire collection with format filtering\ndownload_collection() {\n  local collection=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"  # FLAC, MP3, etc.\n  local max_items=\"${4:-100}\"\n\n  # Get collection items\n  local items=$(get_collection_items \"$collection\" \"$max_items\")\n\n  local count=0\n  while IFS= read -r identifier; do\n    count=$((count + 1))\n    echo \"[$count\u002F$max_items] Downloading: $identifier\"\n\n    # Create item directory\n    local item_dir=\"$output_base\u002F$identifier\"\n    mkdir -p \"$item_dir\"\n\n    # Download with format filter\n    download_item \"$identifier\" \"$item_dir\" \"$format\"\n\n    # Download metadata\n    curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n      > \"$item_dir\u002F.curator\u002Fmetadata.json\"\n\n    # Rate limiting (be nice to archive.org)\n    sleep 2\n  done \u003C\u003C\u003C \"$items\"\n}\n\n# Example: Download first 50 FLAC items from collection\ndownload_collection \"GratefulDead\" \"\u002Fmnt\u002Farchive\u002Fgrateful-dead\" \"Flac\" 50\n```\n\n### Parallel Collection Download\n\n```bash\n# Download collection items in parallel (with concurrency limit)\ndownload_collection_parallel() {\n  local collection=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"\n  local max_concurrent=\"${4:-3}\"\n\n  # Get collection items\n  local items=$(get_collection_items \"$collection\" 1000)\n\n  # Create job queue\n  local queue_file=\"\u002Ftmp\u002Fcurator-archive-queue-$$.txt\"\n  echo \"$items\" > \"$queue_file\"\n\n  # Process queue with concurrency limit\n  cat \"$queue_file\" | xargs -P \"$max_concurrent\" -I {} bash -c \"\n    identifier={}\n    item_dir=\\\"$output_base\u002F\\$identifier\\\"\n    mkdir -p \\\"\\$item_dir\\\"\n\n    echo \\\"Downloading: \\$identifier\\\"\n\n    # Download best quality audio\n    files=\\$(curl -s \\\"https:\u002F\u002Farchive.org\u002Fmetadata\u002F\\$identifier\\\" \\\n      | jq -r '.files[] | select(.format == \\\"$format\\\") | .name')\n\n    while IFS= read -r file; do\n      wget -q --show-progress \\\n        \\\"https:\u002F\u002Farchive.org\u002Fdownload\u002F\\$identifier\u002F\\$file\\\" \\\n        -P \\\"\\$item_dir\\\"\n    done \u003C\u003C\u003C \\\"\\$files\\\"\n\n    # Save metadata\n    curl -s \\\"https:\u002F\u002Farchive.org\u002Fmetadata\u002F\\$identifier\\\" \\\n      > \\\"\\$item_dir\u002F.curator\u002Fmetadata.json\\\"\n\n    sleep 2  # Rate limiting\n  \"\n\n  rm \"$queue_file\"\n}\n```\n\n### wget Recursive Download\n\n```bash\n# Use wget's recursive mode for efficient bulk download\ndownload_with_wget_recursive() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format_pattern=\"$3\"  # e.g., \"*.flac\" or \"*.mp3\"\n\n  mkdir -p \"$output_dir\"\n\n  wget --recursive \\\n       --no-parent \\\n       --no-directories \\\n       --accept \"$format_pattern\" \\\n       --directory-prefix=\"$output_dir\" \\\n       --wait=2 \\\n       --random-wait \\\n       \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F\"\n}\n\n# Example: Download all FLAC files from item\ndownload_with_wget_recursive \"gd1977-05-08.sbd.miller.97065.flac16\" \\\n  \"\u002Fmnt\u002Farchive\u002Fgd-1977-05-08\" \\\n  \"*.flac\"\n```\n\n## Quality Selection Strategy\n\n### Format Preference Hierarchy\n\nFor audio archival, prefer formats in this order:\n\n1. **FLAC** - Lossless, widely supported\n2. **320Kbps MP3** - High quality lossy, universal compatibility\n3. **VBR MP3** - Variable bitrate, good quality\u002Fsize ratio\n4. **Ogg Vorbis** - Good quality, open format\n5. **128Kbps MP3** - Acceptable for spoken word, not music\n\n### Automatic Quality Selection\n\n```bash\n# Select best available format for an item\nselect_best_format() {\n  local identifier=\"$1\"\n\n  # Get available formats\n  local formats=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | .format' | sort -u)\n\n  # Check in preference order\n  if echo \"$formats\" | grep -q \"Flac\"; then\n    echo \"Flac\"\n  elif echo \"$formats\" | grep -q \"320Kbps MP3\"; then\n    echo \"320Kbps MP3\"\n  elif echo \"$formats\" | grep -q \"VBR MP3\"; then\n    echo \"VBR MP3\"\n  elif echo \"$formats\" | grep -q \"Ogg Vorbis\"; then\n    echo \"Ogg Vorbis\"\n  else\n    echo \"$(echo \"$formats\" | grep -i mp3 | head -1)\"\n  fi\n}\n\n# Download using best available format\ndownload_best_quality() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n\n  local best_format=$(select_best_format \"$identifier\")\n\n  echo \"Selected format: $best_format\"\n  download_item \"$identifier\" \"$output_dir\" \"$best_format\"\n}\n```\n\n### Size vs Quality Trade-offs\n\n```bash\n# Estimate download size before acquiring\nestimate_download_size() {\n  local identifier=\"$1\"\n  local format=\"$2\"\n\n  local total_size=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq \"[.files[] | select(.format == \\\"$format\\\") | .size | tonumber] | add\")\n\n  # Convert to human-readable\n  local size_mb=$((total_size \u002F 1048576))\n  local size_gb=$((size_mb \u002F 1024))\n\n  if [[ $size_gb -gt 0 ]]; then\n    echo \"${size_gb}GB\"\n  else\n    echo \"${size_mb}MB\"\n  fi\n}\n\n# Check if size is acceptable before downloading\ndownload_if_acceptable() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format=\"$3\"\n  local max_size_gb=\"${4:-5}\"  # Default 5GB limit\n\n  local estimated_size=$(estimate_download_size \"$identifier\" \"$format\")\n  local size_value=$(echo \"$estimated_size\" | sed 's\u002F[^0-9]\u002F\u002Fg')\n  local size_unit=$(echo \"$estimated_size\" | sed 's\u002F[0-9]\u002F\u002Fg')\n\n  if [[ \"$size_unit\" == \"GB\" && $size_value -gt $max_size_gb ]]; then\n    echo \"SKIPPED: $identifier ($estimated_size exceeds ${max_size_gb}GB limit)\"\n    return 1\n  fi\n\n  echo \"Downloading: $identifier ($estimated_size)\"\n  download_item \"$identifier\" \"$output_dir\" \"$format\"\n}\n```\n\n## Metadata Extraction and Storage\n\n### Extract Archive Metadata\n\n```bash\n# Convert Archive.org metadata to curator format\nextract_archive_metadata() {\n  local identifier=\"$1\"\n  local output_file=\"$2\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" | jq '{\n    source: \"archive.org\",\n    identifier: .metadata.identifier,\n    title: .metadata.title,\n    creator: .metadata.creator,\n    date: .metadata.date,\n    venue: .metadata.venue,\n    coverage: .metadata.coverage,\n    description: .metadata.description,\n    collection: .metadata.collection,\n    downloads: .item_size.downloads,\n    avg_rating: .reviews.info.avg_rating,\n    num_reviews: .reviews.info.num_reviews,\n    files: [\n      .files[] | {\n        name: .name,\n        format: .format,\n        size: .size,\n        md5: .md5,\n        sha1: .sha1\n      }\n    ]\n  }' > \"$output_file\"\n}\n\n# Example usage\nextract_archive_metadata \"gd1977-05-08.sbd.miller.97065.flac16\" \\\n  \".curator\u002Fmetadata\u002Fgd-1977-05-08.json\"\n```\n\n### Merge with Curator Metadata\n\n```bash\n# Merge Archive.org metadata with existing curator metadata\nmerge_metadata() {\n  local curator_metadata=\"$1\"\n  local archive_metadata=\"$2\"\n  local output_file=\"$3\"\n\n  jq -s '.[0] * .[1]' \"$curator_metadata\" \"$archive_metadata\" > \"$output_file\"\n}\n```\n\n## Verification and Quality Assurance\n\n### Checksum Verification\n\nArchive.org provides MD5 and SHA1 checksums for all files:\n\n```bash\n# Verify downloaded files against Archive.org checksums\nverify_archive_downloads() {\n  local identifier=\"$1\"\n  local download_dir=\"$2\"\n\n  # Get checksums from metadata\n  local checksums=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | \"\\(.md5)  \\(.name)\"')\n\n  # Verify each file\n  local failed=0\n  while IFS= read -r line; do\n    local expected_md5=\"${line%%  *}\"\n    local filename=\"${line#*  }\"\n    local filepath=\"$download_dir\u002F$filename\"\n\n    if [[ ! -f \"$filepath\" ]]; then\n      echo \"MISSING: $filename\"\n      failed=$((failed + 1))\n      continue\n    fi\n\n    local actual_md5=$(md5sum \"$filepath\" | awk '{print $1}')\n\n    if [[ \"$actual_md5\" != \"$expected_md5\" ]]; then\n      echo \"CHECKSUM FAILED: $filename\"\n      echo \"  Expected: $expected_md5\"\n      echo \"  Actual:   $actual_md5\"\n      failed=$((failed + 1))\n    else\n      echo \"VERIFIED: $filename\"\n    fi\n  done \u003C\u003C\u003C \"$checksums\"\n\n  if [[ $failed -gt 0 ]]; then\n    echo \"Verification failed for $failed files\"\n    return 1\n  fi\n\n  echo \"All files verified successfully\"\n  return 0\n}\n```\n\n### File Integrity Check\n\n```bash\n# Verify audio file integrity after download\nverify_audio_integrity() {\n  local file=\"$1\"\n\n  # Check file is not zero-byte\n  if [[ ! -s \"$file\" ]]; then\n    echo \"FAILED: Zero-byte file\"\n    return 1\n  fi\n\n  # Verify with ffmpeg\n  if command -v ffmpeg >\u002Fdev\u002Fnull; then\n    if ffmpeg -v error -i \"$file\" -f null - 2>&1 | grep -q \"error\"; then\n      echo \"FAILED: Corrupted audio file\"\n      return 1\n    fi\n  fi\n\n  # FLAC specific: verify with flac tool\n  if [[ \"$file\" == *.flac ]] && command -v flac >\u002Fdev\u002Fnull; then\n    if ! flac -t \"$file\" 2>&1 | grep -q \"ok\"; then\n      echo \"FAILED: FLAC verification failed\"\n      return 1\n    fi\n  fi\n\n  echo \"VERIFIED: $file\"\n  return 0\n}\n\n# Verify all files in directory\nverify_directory_integrity() {\n  local dir=\"$1\"\n\n  local total=0\n  local verified=0\n  local failed=0\n\n  find \"$dir\" -type f \\( -name \"*.flac\" -o -name \"*.mp3\" -o -name \"*.ogg\" \\) | while read -r file; do\n    total=$((total + 1))\n\n    if verify_audio_integrity \"$file\"; then\n      verified=$((verified + 1))\n    else\n      failed=$((failed + 1))\n    fi\n  done\n\n  echo \"Integrity check complete: $verified\u002F$total verified, $failed failed\"\n}\n```\n\n## Rate Limiting and Politeness\n\nArchive.org requests responsible use of their bandwidth:\n\n```bash\n# Implement polite download behavior\npolite_download() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format=\"$3\"\n\n  # Add delays between requests\n  local wait_time=2  # seconds\n\n  # Get file list\n  local files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r \".files[] | select(.format == \\\"$format\\\") | .name\")\n\n  while IFS= read -r file; do\n    echo \"Downloading: $file\"\n\n    wget --quiet \\\n         --show-progress \\\n         --wait=\"$wait_time\" \\\n         --random-wait \\\n         --user-agent=\"AIWG-MediaCurator\u002F1.0 (research\u002Fpersonal use)\" \\\n         \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F$file\" \\\n         -P \"$output_dir\"\n\n  done \u003C\u003C\u003C \"$files\"\n}\n```\n\n### Bulk Download Best Practices\n\n1. **Rate limit**: Wait 2-5 seconds between requests\n2. **Random wait**: Add jitter to avoid patterns\n3. **User agent**: Identify your tool\n4. **Off-peak hours**: Download during US night hours\n5. **Resume support**: Use `wget -c` to resume interrupted downloads\n6. **Error handling**: Retry failed downloads after delay\n\n## Collection Management\n\n### Build Local Collection Index\n\n```bash\n# Create searchable index of downloaded items\nbuild_collection_index() {\n  local collection_dir=\"$1\"\n  local index_file=\"$2\"\n\n  echo '{\"items\": []}' > \"$index_file\"\n\n  find \"$collection_dir\" -name \"metadata.json\" -type f | while read -r metadata_file; do\n    local item_dir=$(dirname \"$metadata_file\")\n\n    # Extract key metadata fields\n    local item_data=$(jq '{\n      identifier: .metadata.identifier,\n      title: .metadata.title,\n      creator: .metadata.creator,\n      date: .metadata.date,\n      local_path: \"'\"$item_dir\"'\",\n      file_count: (.files | length),\n      total_size: ([.files[] | .size | tonumber] | add)\n    }' \"$metadata_file\")\n\n    # Append to index\n    jq \".items += [$item_data]\" \"$index_file\" > \"$index_file.tmp\"\n    mv \"$index_file.tmp\" \"$index_file\"\n  done\n\n  echo \"Index built: $index_file\"\n}\n\n# Search local collection\nsearch_local_collection() {\n  local index_file=\"$1\"\n  local query=\"$2\"\n\n  jq -r \".items[] | select(.title | test(\\\"$query\\\"; \\\"i\\\")) | \\\"\\(.date) - \\(.creator) - \\(.title) (\\(.local_path))\\\"\" \\\n    \"$index_file\"\n}\n```\n\n### Deduplicate Collection\n\n```bash\n# Find and remove duplicate items in collection\ndeduplicate_collection() {\n  local collection_dir=\"$1\"\n\n  # Build checksum database\n  local checksum_file=\"\u002Ftmp\u002Fcurator-checksums-$$.txt\"\n\n  find \"$collection_dir\" -type f \\( -name \"*.flac\" -o -name \"*.mp3\" \\) | while read -r file; do\n    local checksum=$(md5sum \"$file\" | awk '{print $1}')\n    echo \"$checksum  $file\" >> \"$checksum_file\"\n  done\n\n  # Find duplicates\n  sort \"$checksum_file\" | uniq -d -w 32 | while read -r line; do\n    local checksum=\"${line%%  *}\"\n\n    echo \"Duplicate found (checksum: $checksum):\"\n\n    grep \"^$checksum\" \"$checksum_file\" | while read -r dup_line; do\n      local dup_file=\"${dup_line#*  }\"\n      echo \"  - $dup_file\"\n    done\n\n    # Offer to delete all but first\n    local files=($(grep \"^$checksum\" \"$checksum_file\" | cut -d' ' -f3-))\n    local keep=\"${files[0]}\"\n\n    echo \"Keep: $keep\"\n\n    for ((i=1; i\u003C${#files[@]}; i++)); do\n      echo \"Delete: ${files[$i]}\"\n      rm \"${files[$i]}\"\n    done\n  done\n\n  rm \"$checksum_file\"\n}\n```\n\n## Advanced Patterns\n\n### Incremental Collection Sync\n\n```bash\n# Download only new items added to collection since last sync\nsync_collection_incremental() {\n  local collection=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"\n  local sync_state_file=\"$output_base\u002F.curator\u002Fsync-state.json\"\n\n  # Get last sync timestamp\n  local last_sync\n  if [[ -f \"$sync_state_file\" ]]; then\n    last_sync=$(jq -r '.last_sync' \"$sync_state_file\")\n  else\n    last_sync=\"1970-01-01\"\n  fi\n\n  # Search for items added\u002Fupdated since last sync\n  local new_items=$(curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=collection:$collection AND publicdate:[$last_sync TO null]\" \\\n    -d \"fl[]=identifier\" \\\n    -d \"rows=1000\" \\\n    -d \"output=json\" \\\n    | jq -r '.response.docs[] | .identifier')\n\n  # Download new items\n  local count=0\n  while IFS= read -r identifier; do\n    count=$((count + 1))\n    echo \"Downloading new item [$count]: $identifier\"\n\n    download_item \"$identifier\" \"$output_base\u002F$identifier\" \"$format\"\n    sleep 2\n  done \u003C\u003C\u003C \"$new_items\"\n\n  # Update sync state\n  echo \"{\\\"last_sync\\\": \\\"$(date -Iseconds)\\\", \\\"items_added\\\": $count}\" > \"$sync_state_file\"\n\n  echo \"Sync complete: $count new items added\"\n}\n```\n\n### Filtered Batch Download\n\n```bash\n# Download items matching complex filter criteria\ndownload_filtered_batch() {\n  local query=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"\n  local min_rating=\"${4:-4.0}\"\n  local min_year=\"${5:-1960}\"\n\n  # Search with filters\n  local items=$(curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=$query AND avg_rating:[$min_rating TO 5.0] AND year:[$min_year TO 2026]\" \\\n    -d \"fl[]=identifier,avg_rating,year\" \\\n    -d \"rows=500\" \\\n    -d \"output=json\")\n\n  # Download each item\n  echo \"$items\" | jq -r '.response.docs[] | .identifier' | while read -r identifier; do\n    local rating=$(echo \"$items\" | jq -r \".response.docs[] | select(.identifier == \\\"$identifier\\\") | .avg_rating\")\n    local year=$(echo \"$items\" | jq -r \".response.docs[] | select(.identifier == \\\"$identifier\\\") | .year\")\n\n    echo \"Downloading: $identifier (rating: $rating, year: $year)\"\n\n    download_item \"$identifier\" \"$output_base\u002F$identifier\" \"$format\"\n    sleep 2\n  done\n}\n```\n\n## Integration with Media Curator Framework\n\n### Source Plan Generation\n\n```bash\n# Generate source plan for \u002Facquire command\ngenerate_archive_source_plan() {\n  local collection=\"$1\"\n  local output_file=\"$2\"\n  local format=\"${3:-Flac}\"\n\n  # Get collection items\n  local items=$(get_collection_items \"$collection\" 100)\n\n  # Build YAML plan\n  cat > \"$output_file\" \u003C\u003CEOF\nsource_plan:\n  id: archive-$(date +%Y%m%d-%H%M%S)\n  source: archive.org\n  collection: $collection\n  format: $format\n  created_at: $(date -Iseconds)\n\nsources:\nEOF\n\n  while IFS= read -r identifier; do\n    # Get item metadata\n    local metadata=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\")\n    local title=$(echo \"$metadata\" | jq -r '.metadata.title')\n    local creator=$(echo \"$metadata\" | jq -r '.metadata.creator')\n    local date=$(echo \"$metadata\" | jq -r '.metadata.date')\n\n    cat >> \"$output_file\" \u003C\u003CEOF\n  - identifier: $identifier\n    title: \"$title\"\n    creator: \"$creator\"\n    date: \"$date\"\n    url: \"https:\u002F\u002Farchive.org\u002Fdetails\u002F$identifier\"\n    format: $format\nEOF\n\n  done \u003C\u003C\u003C \"$items\"\n\n  echo \"Source plan generated: $output_file\"\n}\n\n# Usage with \u002Facquire\n# generate_archive_source_plan \"GratefulDead\" \".curator\u002Fsources\u002Fgd-plan.yaml\" \"Flac\"\n# \u002Facquire --plan .curator\u002Fsources\u002Fgd-plan.yaml\n```\n\n## Troubleshooting\n\n### Common Issues and Solutions\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| **Download fails immediately** | Invalid identifier | Verify identifier on archive.org website |\n| **Slow download speeds** | Network throttling | Use `--limit-rate` with wget |\n| **Incomplete files** | Connection timeout | Use `wget -c` to resume |\n| **Missing files** | Format not available | Check available formats with metadata API |\n| **Checksum mismatch** | Corrupted download | Delete and re-download |\n| **Rate limiting** | Too many requests | Increase wait time between downloads |\n\n### Debug Mode\n\n```bash\n# Enable verbose output for troubleshooting\nexport CURATOR_DEBUG=1\n\ndownload_item_debug() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n\n  if [[ \"$CURATOR_DEBUG\" == \"1\" ]]; then\n    set -x  # Enable bash tracing\n  fi\n\n  # Get metadata with verbose curl\n  curl -v \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" 2>&1 | tee \"$output_dir\u002F.curator\u002Fmetadata-debug.log\"\n\n  # Download with verbose wget\n  wget --verbose \\\n       --debug \\\n       \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F\" \\\n       2>&1 | tee \"$output_dir\u002F.curator\u002Fdownload-debug.log\"\n\n  set +x\n}\n```\n\n## Performance Optimization\n\n### Parallel Download Tuning\n\n```bash\n# Optimal concurrent downloads based on connection speed\ndetermine_optimal_parallelism() {\n  local speed_mbps=\"$1\"\n\n  if [[ $speed_mbps -lt 10 ]]; then\n    echo 2  # Slow connection\n  elif [[ $speed_mbps -lt 50 ]]; then\n    echo 3  # Medium connection\n  elif [[ $speed_mbps -lt 100 ]]; then\n    echo 5  # Fast connection\n  else\n    echo 8  # Very fast connection\n  fi\n}\n\n# Test connection speed\ntest_connection_speed() {\n  # Download test file and measure speed\n  local test_file=\"https:\u002F\u002Farchive.org\u002Fdownload\u002Ftest_item\u002Ftest.mp3\"\n  local start_time=$(date +%s)\n\n  wget -q -O \u002Ftmp\u002Fspeed-test.tmp \"$test_file\"\n\n  local end_time=$(date +%s)\n  local duration=$((end_time - start_time))\n  local size=$(stat -c%s \u002Ftmp\u002Fspeed-test.tmp 2>\u002Fdev\u002Fnull || stat -f%z \u002Ftmp\u002Fspeed-test.tmp)\n  local speed_mbps=$(( (size * 8) \u002F (duration * 1000000) ))\n\n  rm \u002Ftmp\u002Fspeed-test.tmp\n\n  echo \"$speed_mbps\"\n}\n```\n\n### Caching Strategy\n\n```bash\n# Cache metadata to reduce API calls\ncache_metadata() {\n  local identifier=\"$1\"\n  local cache_dir=\".curator\u002Fcache\u002Fmetadata\"\n  local cache_file=\"$cache_dir\u002F$identifier.json\"\n\n  mkdir -p \"$cache_dir\"\n\n  # Check cache age\n  if [[ -f \"$cache_file\" ]]; then\n    local cache_age=$(( $(date +%s) - $(stat -c%Y \"$cache_file\" 2>\u002Fdev\u002Fnull || stat -f%m \"$cache_file\") ))\n\n    # Cache valid for 7 days\n    if [[ $cache_age -lt 604800 ]]; then\n      cat \"$cache_file\"\n      return 0\n    fi\n  fi\n\n  # Fetch and cache\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" | tee \"$cache_file\"\n}\n```\n\n## Summary\n\nArchive Acquisition skill provides:\n\n- **Discovery**: Search API patterns for finding content\n- **Quality Selection**: Automatic best-format selection (prefer FLAC, accept MP3 320K)\n- **Bulk Download**: Recursive wget and parallel download patterns\n- **Verification**: Checksum validation and integrity checks\n- **Collection Management**: Indexing, deduplication, incremental sync\n- **Integration**: Source plan generation for `\u002Facquire` command\n- **Performance**: Parallel tuning, caching, rate limiting\n\nUse this skill whenever working with Internet Archive content in the Media Curator framework.\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fhuman-authorization.md — Seek explicit authorization before bulk downloads and irreversible archive operations\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fresearch-before-decision.md — Evaluate archive item quality and metadata before committing to download\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Facquire\u002FSKILL.md — General acquisition skill that delegates to archive-acquisition for archive.org sources\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fintegrity-verification\u002FSKILL.md — Verify checksums after archive downloads\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fquality-filtering\u002FSKILL.md — Quality scoring used to select best format from archive items\n","# Archive Acquisition Skill\n\nSpecialized patterns and techniques for acquiring media content from Internet Archive (archive.org) and other archival sources. Focuses on bulk downloads, quality selection, format filtering, and collection management.\n\n## Internet Archive Overview\n\nInternet Archive hosts massive collections of audio, video, text, and software. Key characteristics:\n\n- **Open access**: Most content freely downloadable\n- **Multiple formats**: Same item often available in FLAC, MP3, OGG, etc.\n- **Collections**: Items grouped by uploader, topic, or curator\n- **Metadata**: Rich JSON metadata for every item\n- **API access**: Full programmatic access via REST API\n\n## Discovery Patterns\n\n### Search API\n\nFind items matching specific criteria:\n\n```bash\n# Search for items by keyword and mediatype\nsearch_archive() {\n  local query=\"$1\"\n  local mediatype=\"$2\"  # audio, movies, texts, etc.\n  local rows=\"${3:-100}\"  # Results per page\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=$query AND mediatype:$mediatype\" \\\n    -d \"fl[]=identifier,title,creator,date,format\" \\\n    -d \"rows=$rows\" \\\n    -d \"output=json\" \\\n    | jq '.response.docs[]'\n}\n\n# Example: Search for Grateful Dead concerts\nsearch_archive \"grateful dead\" \"audio\" 50\n```\n\n### Response Format\n\n```json\n{\n  \"identifier\": \"gd1977-05-08.sbd.miller.97065.flac16\",\n  \"title\": \"Grateful Dead Live at Barton Hall on 1977-05-08\",\n  \"creator\": \"Grateful Dead\",\n  \"date\": \"1977-05-08\",\n  \"format\": [\"Flac\", \"VBR MP3\", \"Ogg Vorbis\", \"Metadata\"]\n}\n```\n\n### Collection Browsing\n\nList all items in a collection:\n\n```bash\n# Get items from a specific collection\nget_collection_items() {\n  local collection=\"$1\"\n  local rows=\"${2:-1000}\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=collection:$collection\" \\\n    -d \"fl[]=identifier,title,format\" \\\n    -d \"rows=$rows\" \\\n    -d \"output=json\" \\\n    | jq -r '.response.docs[] | .identifier'\n}\n\n# Example: Get all items from GratefulDead collection\nget_collection_items \"GratefulDead\" 500\n```\n\n### Advanced Query Patterns\n\n```bash\n# Find items by date range\nsearch_by_date() {\n  local creator=\"$1\"\n  local start_date=\"$2\"  # YYYY-MM-DD\n  local end_date=\"$3\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=creator:\\\"$creator\\\" AND date:[$start_date TO $end_date]\" \\\n    -d \"fl[]=identifier,title,date\" \\\n    -d \"rows=100\" \\\n    -d \"output=json\" \\\n    | jq '.response.docs[]'\n}\n\n# Find items with specific format available\nsearch_by_format() {\n  local query=\"$1\"\n  local format=\"$2\"  # FLAC, MP3, etc.\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=$query AND format:$format\" \\\n    -d \"fl[]=identifier,title,format\" \\\n    -d \"rows=100\" \\\n    -d \"output=json\" \\\n    | jq '.response.docs[]'\n}\n\n# Example: Find all FLAC recordings of specific artist\nsearch_by_format \"pink floyd\" \"Flac\"\n```\n\n## Item Metadata Retrieval\n\n### Get Item Details\n\n```bash\n# Retrieve full metadata for an item\nget_item_metadata() {\n  local identifier=\"$1\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq '.'\n}\n\n# Extract specific metadata fields\nget_item_files() {\n  local identifier=\"$1\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format != \"Metadata\") | \"\\(.name)\\t\\(.format)\\t\\(.size)\"'\n}\n\n# Example output:\n# gd77-05-08d1t01.flac    Flac    45123456\n# gd77-05-08d1t01.mp3     VBR MP3 12345678\n```\n\n### Filter by Format\n\n```bash\n# Get only FLAC files from an item\nget_flac_files() {\n  local identifier=\"$1\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format == \"Flac\") | .name'\n}\n\n# Get best quality audio files (prefer FLAC, fallback to 320K MP3)\nget_best_audio_files() {\n  local identifier=\"$1\"\n\n  # Try FLAC first\n  local flac_files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format == \"Flac\") | .name')\n\n  if [[ -n \"$flac_files\" ]]; then\n    echo \"$flac_files\"\n    return 0\n  fi\n\n  # Fallback to highest bitrate MP3\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | select(.format == \"VBR MP3\" or .format == \"320Kbps MP3\") | .name'\n}\n```\n\n## Download Patterns\n\n### Single Item Download\n\n```bash\n# Download all files from a single item\ndownload_item() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format_filter=\"$3\"  # Optional: FLAC, MP3, etc.\n\n  mkdir -p \"$output_dir\"\n\n  # Get file list\n  local files\n  if [[ -n \"$format_filter\" ]]; then\n    files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n      | jq -r \".files[] | select(.format == \\\"$format_filter\\\") | .name\")\n  else\n    files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n      | jq -r '.files[] | select(.format != \"Metadata\") | .name')\n  fi\n\n  # Download each file\n  while IFS= read -r file; do\n    echo \"Downloading: $file\"\n    wget -q --show-progress \\\n      \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F$file\" \\\n      -P \"$output_dir\"\n  done \u003C\u003C\u003C \"$files\"\n}\n\n# Example: Download all FLAC files from an item\ndownload_item \"gd1977-05-08.sbd.miller.97065.flac16\" \"\u002Fmnt\u002Farchive\u002Fgrateful-dead\u002F1977-05-08\" \"Flac\"\n```\n\n### Recursive Collection Download\n\n```bash\n# Download entire collection with format filtering\ndownload_collection() {\n  local collection=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"  # FLAC, MP3, etc.\n  local max_items=\"${4:-100}\"\n\n  # Get collection items\n  local items=$(get_collection_items \"$collection\" \"$max_items\")\n\n  local count=0\n  while IFS= read -r identifier; do\n    count=$((count + 1))\n    echo \"[$count\u002F$max_items] Downloading: $identifier\"\n\n    # Create item directory\n    local item_dir=\"$output_base\u002F$identifier\"\n    mkdir -p \"$item_dir\"\n\n    # Download with format filter\n    download_item \"$identifier\" \"$item_dir\" \"$format\"\n\n    # Download metadata\n    curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n      > \"$item_dir\u002F.curator\u002Fmetadata.json\"\n\n    # Rate limiting (be nice to archive.org)\n    sleep 2\n  done \u003C\u003C\u003C \"$items\"\n}\n\n# Example: Download first 50 FLAC items from collection\ndownload_collection \"GratefulDead\" \"\u002Fmnt\u002Farchive\u002Fgrateful-dead\" \"Flac\" 50\n```\n\n### Parallel Collection Download\n\n```bash\n# Download collection items in parallel (with concurrency limit)\ndownload_collection_parallel() {\n  local collection=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"\n  local max_concurrent=\"${4:-3}\"\n\n  # Get collection items\n  local items=$(get_collection_items \"$collection\" 1000)\n\n  # Create job queue\n  local queue_file=\"\u002Ftmp\u002Fcurator-archive-queue-$$.txt\"\n  echo \"$items\" > \"$queue_file\"\n\n  # Process queue with concurrency limit\n  cat \"$queue_file\" | xargs -P \"$max_concurrent\" -I {} bash -c \"\n    identifier={}\n    item_dir=\\\"$output_base\u002F\\$identifier\\\"\n    mkdir -p \\\"\\$item_dir\\\"\n\n    echo \\\"Downloading: \\$identifier\\\"\n\n    # Download best quality audio\n    files=\\$(curl -s \\\"https:\u002F\u002Farchive.org\u002Fmetadata\u002F\\$identifier\\\" \\\n      | jq -r '.files[] | select(.format == \\\"$format\\\") | .name')\n\n    while IFS= read -r file; do\n      wget -q --show-progress \\\n        \\\"https:\u002F\u002Farchive.org\u002Fdownload\u002F\\$identifier\u002F\\$file\\\" \\\n        -P \\\"\\$item_dir\\\"\n    done \u003C\u003C\u003C \\\"\\$files\\\"\n\n    # Save metadata\n    curl -s \\\"https:\u002F\u002Farchive.org\u002Fmetadata\u002F\\$identifier\\\" \\\n      > \\\"\\$item_dir\u002F.curator\u002Fmetadata.json\\\"\n\n    sleep 2  # Rate limiting\n  \"\n\n  rm \"$queue_file\"\n}\n```\n\n### wget Recursive Download\n\n```bash\n# Use wget's recursive mode for efficient bulk download\ndownload_with_wget_recursive() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format_pattern=\"$3\"  # e.g., \"*.flac\" or \"*.mp3\"\n\n  mkdir -p \"$output_dir\"\n\n  wget --recursive \\\n       --no-parent \\\n       --no-directories \\\n       --accept \"$format_pattern\" \\\n       --directory-prefix=\"$output_dir\" \\\n       --wait=2 \\\n       --random-wait \\\n       \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F\"\n}\n\n# Example: Download all FLAC files from item\ndownload_with_wget_recursive \"gd1977-05-08.sbd.miller.97065.flac16\" \\\n  \"\u002Fmnt\u002Farchive\u002Fgd-1977-05-08\" \\\n  \"*.flac\"\n```\n\n## Quality Selection Strategy\n\n### Format Preference Hierarchy\n\nFor audio archival, prefer formats in this order:\n\n1. **FLAC** - Lossless, widely supported\n2. **320Kbps MP3** - High quality lossy, universal compatibility\n3. **VBR MP3** - Variable bitrate, good quality\u002Fsize ratio\n4. **Ogg Vorbis** - Good quality, open format\n5. **128Kbps MP3** - Acceptable for spoken word, not music\n\n### Automatic Quality Selection\n\n```bash\n# Select best available format for an item\nselect_best_format() {\n  local identifier=\"$1\"\n\n  # Get available formats\n  local formats=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | .format' | sort -u)\n\n  # Check in preference order\n  if echo \"$formats\" | grep -q \"Flac\"; then\n    echo \"Flac\"\n  elif echo \"$formats\" | grep -q \"320Kbps MP3\"; then\n    echo \"320Kbps MP3\"\n  elif echo \"$formats\" | grep -q \"VBR MP3\"; then\n    echo \"VBR MP3\"\n  elif echo \"$formats\" | grep -q \"Ogg Vorbis\"; then\n    echo \"Ogg Vorbis\"\n  else\n    echo \"$(echo \"$formats\" | grep -i mp3 | head -1)\"\n  fi\n}\n\n# Download using best available format\ndownload_best_quality() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n\n  local best_format=$(select_best_format \"$identifier\")\n\n  echo \"Selected format: $best_format\"\n  download_item \"$identifier\" \"$output_dir\" \"$best_format\"\n}\n```\n\n### Size vs Quality Trade-offs\n\n```bash\n# Estimate download size before acquiring\nestimate_download_size() {\n  local identifier=\"$1\"\n  local format=\"$2\"\n\n  local total_size=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq \"[.files[] | select(.format == \\\"$format\\\") | .size | tonumber] | add\")\n\n  # Convert to human-readable\n  local size_mb=$((total_size \u002F 1048576))\n  local size_gb=$((size_mb \u002F 1024))\n\n  if [[ $size_gb -gt 0 ]]; then\n    echo \"${size_gb}GB\"\n  else\n    echo \"${size_mb}MB\"\n  fi\n}\n\n# Check if size is acceptable before downloading\ndownload_if_acceptable() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format=\"$3\"\n  local max_size_gb=\"${4:-5}\"  # Default 5GB limit\n\n  local estimated_size=$(estimate_download_size \"$identifier\" \"$format\")\n  local size_value=$(echo \"$estimated_size\" | sed 's\u002F[^0-9]\u002F\u002Fg')\n  local size_unit=$(echo \"$estimated_size\" | sed 's\u002F[0-9]\u002F\u002Fg')\n\n  if [[ \"$size_unit\" == \"GB\" && $size_value -gt $max_size_gb ]]; then\n    echo \"SKIPPED: $identifier ($estimated_size exceeds ${max_size_gb}GB limit)\"\n    return 1\n  fi\n\n  echo \"Downloading: $identifier ($estimated_size)\"\n  download_item \"$identifier\" \"$output_dir\" \"$format\"\n}\n```\n\n## Metadata Extraction and Storage\n\n### Extract Archive Metadata\n\n```bash\n# Convert Archive.org metadata to curator format\nextract_archive_metadata() {\n  local identifier=\"$1\"\n  local output_file=\"$2\"\n\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" | jq '{\n    source: \"archive.org\",\n    identifier: .metadata.identifier,\n    title: .metadata.title,\n    creator: .metadata.creator,\n    date: .metadata.date,\n    venue: .metadata.venue,\n    coverage: .metadata.coverage,\n    description: .metadata.description,\n    collection: .metadata.collection,\n    downloads: .item_size.downloads,\n    avg_rating: .reviews.info.avg_rating,\n    num_reviews: .reviews.info.num_reviews,\n    files: [\n      .files[] | {\n        name: .name,\n        format: .format,\n        size: .size,\n        md5: .md5,\n        sha1: .sha1\n      }\n    ]\n  }' > \"$output_file\"\n}\n\n# Example usage\nextract_archive_metadata \"gd1977-05-08.sbd.miller.97065.flac16\" \\\n  \".curator\u002Fmetadata\u002Fgd-1977-05-08.json\"\n```\n\n### Merge with Curator Metadata\n\n```bash\n# Merge Archive.org metadata with existing curator metadata\nmerge_metadata() {\n  local curator_metadata=\"$1\"\n  local archive_metadata=\"$2\"\n  local output_file=\"$3\"\n\n  jq -s '.[0] * .[1]' \"$curator_metadata\" \"$archive_metadata\" > \"$output_file\"\n}\n```\n\n## Verification and Quality Assurance\n\n### Checksum Verification\n\nArchive.org provides MD5 and SHA1 checksums for all files:\n\n```bash\n# Verify downloaded files against Archive.org checksums\nverify_archive_downloads() {\n  local identifier=\"$1\"\n  local download_dir=\"$2\"\n\n  # Get checksums from metadata\n  local checksums=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r '.files[] | \"\\(.md5)  \\(.name)\"')\n\n  # Verify each file\n  local failed=0\n  while IFS= read -r line; do\n    local expected_md5=\"${line%%  *}\"\n    local filename=\"${line#*  }\"\n    local filepath=\"$download_dir\u002F$filename\"\n\n    if [[ ! -f \"$filepath\" ]]; then\n      echo \"MISSING: $filename\"\n      failed=$((failed + 1))\n      continue\n    fi\n\n    local actual_md5=$(md5sum \"$filepath\" | awk '{print $1}')\n\n    if [[ \"$actual_md5\" != \"$expected_md5\" ]]; then\n      echo \"CHECKSUM FAILED: $filename\"\n      echo \"  Expected: $expected_md5\"\n      echo \"  Actual:   $actual_md5\"\n      failed=$((failed + 1))\n    else\n      echo \"VERIFIED: $filename\"\n    fi\n  done \u003C\u003C\u003C \"$checksums\"\n\n  if [[ $failed -gt 0 ]]; then\n    echo \"Verification failed for $failed files\"\n    return 1\n  fi\n\n  echo \"All files verified successfully\"\n  return 0\n}\n```\n\n### File Integrity Check\n\n```bash\n# Verify audio file integrity after download\nverify_audio_integrity() {\n  local file=\"$1\"\n\n  # Check file is not zero-byte\n  if [[ ! -s \"$file\" ]]; then\n    echo \"FAILED: Zero-byte file\"\n    return 1\n  fi\n\n  # Verify with ffmpeg\n  if command -v ffmpeg >\u002Fdev\u002Fnull; then\n    if ffmpeg -v error -i \"$file\" -f null - 2>&1 | grep -q \"error\"; then\n      echo \"FAILED: Corrupted audio file\"\n      return 1\n    fi\n  fi\n\n  # FLAC specific: verify with flac tool\n  if [[ \"$file\" == *.flac ]] && command -v flac >\u002Fdev\u002Fnull; then\n    if ! flac -t \"$file\" 2>&1 | grep -q \"ok\"; then\n      echo \"FAILED: FLAC verification failed\"\n      return 1\n    fi\n  fi\n\n  echo \"VERIFIED: $file\"\n  return 0\n}\n\n# Verify all files in directory\nverify_directory_integrity() {\n  local dir=\"$1\"\n\n  local total=0\n  local verified=0\n  local failed=0\n\n  find \"$dir\" -type f \\( -name \"*.flac\" -o -name \"*.mp3\" -o -name \"*.ogg\" \\) | while read -r file; do\n    total=$((total + 1))\n\n    if verify_audio_integrity \"$file\"; then\n      verified=$((verified + 1))\n    else\n      failed=$((failed + 1))\n    fi\n  done\n\n  echo \"Integrity check complete: $verified\u002F$total verified, $failed failed\"\n}\n```\n\n## Rate Limiting and Politeness\n\nArchive.org requests responsible use of their bandwidth:\n\n```bash\n# Implement polite download behavior\npolite_download() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n  local format=\"$3\"\n\n  # Add delays between requests\n  local wait_time=2  # seconds\n\n  # Get file list\n  local files=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" \\\n    | jq -r \".files[] | select(.format == \\\"$format\\\") | .name\")\n\n  while IFS= read -r file; do\n    echo \"Downloading: $file\"\n\n    wget --quiet \\\n         --show-progress \\\n         --wait=\"$wait_time\" \\\n         --random-wait \\\n         --user-agent=\"AIWG-MediaCurator\u002F1.0 (research\u002Fpersonal use)\" \\\n         \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F$file\" \\\n         -P \"$output_dir\"\n\n  done \u003C\u003C\u003C \"$files\"\n}\n```\n\n### Bulk Download Best Practices\n\n1. **Rate limit**: Wait 2-5 seconds between requests\n2. **Random wait**: Add jitter to avoid patterns\n3. **User agent**: Identify your tool\n4. **Off-peak hours**: Download during US night hours\n5. **Resume support**: Use `wget -c` to resume interrupted downloads\n6. **Error handling**: Retry failed downloads after delay\n\n## Collection Management\n\n### Build Local Collection Index\n\n```bash\n# Create searchable index of downloaded items\nbuild_collection_index() {\n  local collection_dir=\"$1\"\n  local index_file=\"$2\"\n\n  echo '{\"items\": []}' > \"$index_file\"\n\n  find \"$collection_dir\" -name \"metadata.json\" -type f | while read -r metadata_file; do\n    local item_dir=$(dirname \"$metadata_file\")\n\n    # Extract key metadata fields\n    local item_data=$(jq '{\n      identifier: .metadata.identifier,\n      title: .metadata.title,\n      creator: .metadata.creator,\n      date: .metadata.date,\n      local_path: \"'\"$item_dir\"'\",\n      file_count: (.files | length),\n      total_size: ([.files[] | .size | tonumber] | add)\n    }' \"$metadata_file\")\n\n    # Append to index\n    jq \".items += [$item_data]\" \"$index_file\" > \"$index_file.tmp\"\n    mv \"$index_file.tmp\" \"$index_file\"\n  done\n\n  echo \"Index built: $index_file\"\n}\n\n# Search local collection\nsearch_local_collection() {\n  local index_file=\"$1\"\n  local query=\"$2\"\n\n  jq -r \".items[] | select(.title | test(\\\"$query\\\"; \\\"i\\\")) | \\\"\\(.date) - \\(.creator) - \\(.title) (\\(.local_path))\\\"\" \\\n    \"$index_file\"\n}\n```\n\n### Deduplicate Collection\n\n```bash\n# Find and remove duplicate items in collection\ndeduplicate_collection() {\n  local collection_dir=\"$1\"\n\n  # Build checksum database\n  local checksum_file=\"\u002Ftmp\u002Fcurator-checksums-$$.txt\"\n\n  find \"$collection_dir\" -type f \\( -name \"*.flac\" -o -name \"*.mp3\" \\) | while read -r file; do\n    local checksum=$(md5sum \"$file\" | awk '{print $1}')\n    echo \"$checksum  $file\" >> \"$checksum_file\"\n  done\n\n  # Find duplicates\n  sort \"$checksum_file\" | uniq -d -w 32 | while read -r line; do\n    local checksum=\"${line%%  *}\"\n\n    echo \"Duplicate found (checksum: $checksum):\"\n\n    grep \"^$checksum\" \"$checksum_file\" | while read -r dup_line; do\n      local dup_file=\"${dup_line#*  }\"\n      echo \"  - $dup_file\"\n    done\n\n    # Offer to delete all but first\n    local files=($(grep \"^$checksum\" \"$checksum_file\" | cut -d' ' -f3-))\n    local keep=\"${files[0]}\"\n\n    echo \"Keep: $keep\"\n\n    for ((i=1; i\u003C${#files[@]}; i++)); do\n      echo \"Delete: ${files[$i]}\"\n      rm \"${files[$i]}\"\n    done\n  done\n\n  rm \"$checksum_file\"\n}\n```\n\n## Advanced Patterns\n\n### Incremental Collection Sync\n\n```bash\n# Download only new items added to collection since last sync\nsync_collection_incremental() {\n  local collection=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"\n  local sync_state_file=\"$output_base\u002F.curator\u002Fsync-state.json\"\n\n  # Get last sync timestamp\n  local last_sync\n  if [[ -f \"$sync_state_file\" ]]; then\n    last_sync=$(jq -r '.last_sync' \"$sync_state_file\")\n  else\n    last_sync=\"1970-01-01\"\n  fi\n\n  # Search for items added\u002Fupdated since last sync\n  local new_items=$(curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=collection:$collection AND publicdate:[$last_sync TO null]\" \\\n    -d \"fl[]=identifier\" \\\n    -d \"rows=1000\" \\\n    -d \"output=json\" \\\n    | jq -r '.response.docs[] | .identifier')\n\n  # Download new items\n  local count=0\n  while IFS= read -r identifier; do\n    count=$((count + 1))\n    echo \"Downloading new item [$count]: $identifier\"\n\n    download_item \"$identifier\" \"$output_base\u002F$identifier\" \"$format\"\n    sleep 2\n  done \u003C\u003C\u003C \"$new_items\"\n\n  # Update sync state\n  echo \"{\\\"last_sync\\\": \\\"$(date -Iseconds)\\\", \\\"items_added\\\": $count}\" > \"$sync_state_file\"\n\n  echo \"Sync complete: $count new items added\"\n}\n```\n\n### Filtered Batch Download\n\n```bash\n# Download items matching complex filter criteria\ndownload_filtered_batch() {\n  local query=\"$1\"\n  local output_base=\"$2\"\n  local format=\"$3\"\n  local min_rating=\"${4:-4.0}\"\n  local min_year=\"${5:-1960}\"\n\n  # Search with filters\n  local items=$(curl -s \"https:\u002F\u002Farchive.org\u002Fadvancedsearch.php\" \\\n    -d \"q=$query AND avg_rating:[$min_rating TO 5.0] AND year:[$min_year TO 2026]\" \\\n    -d \"fl[]=identifier,avg_rating,year\" \\\n    -d \"rows=500\" \\\n    -d \"output=json\")\n\n  # Download each item\n  echo \"$items\" | jq -r '.response.docs[] | .identifier' | while read -r identifier; do\n    local rating=$(echo \"$items\" | jq -r \".response.docs[] | select(.identifier == \\\"$identifier\\\") | .avg_rating\")\n    local year=$(echo \"$items\" | jq -r \".response.docs[] | select(.identifier == \\\"$identifier\\\") | .year\")\n\n    echo \"Downloading: $identifier (rating: $rating, year: $year)\"\n\n    download_item \"$identifier\" \"$output_base\u002F$identifier\" \"$format\"\n    sleep 2\n  done\n}\n```\n\n## Integration with Media Curator Framework\n\n### Source Plan Generation\n\n```bash\n# Generate source plan for \u002Facquire command\ngenerate_archive_source_plan() {\n  local collection=\"$1\"\n  local output_file=\"$2\"\n  local format=\"${3:-Flac}\"\n\n  # Get collection items\n  local items=$(get_collection_items \"$collection\" 100)\n\n  # Build YAML plan\n  cat > \"$output_file\" \u003C\u003CEOF\nsource_plan:\n  id: archive-$(date +%Y%m%d-%H%M%S)\n  source: archive.org\n  collection: $collection\n  format: $format\n  created_at: $(date -Iseconds)\n\nsources:\nEOF\n\n  while IFS= read -r identifier; do\n    # Get item metadata\n    local metadata=$(curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\")\n    local title=$(echo \"$metadata\" | jq -r '.metadata.title')\n    local creator=$(echo \"$metadata\" | jq -r '.metadata.creator')\n    local date=$(echo \"$metadata\" | jq -r '.metadata.date')\n\n    cat >> \"$output_file\" \u003C\u003CEOF\n  - identifier: $identifier\n    title: \"$title\"\n    creator: \"$creator\"\n    date: \"$date\"\n    url: \"https:\u002F\u002Farchive.org\u002Fdetails\u002F$identifier\"\n    format: $format\nEOF\n\n  done \u003C\u003C\u003C \"$items\"\n\n  echo \"Source plan generated: $output_file\"\n}\n\n# Usage with \u002Facquire\n# generate_archive_source_plan \"GratefulDead\" \".curator\u002Fsources\u002Fgd-plan.yaml\" \"Flac\"\n# \u002Facquire --plan .curator\u002Fsources\u002Fgd-plan.yaml\n```\n\n## Troubleshooting\n\n### Common Issues and Solutions\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| **Download fails immediately** | Invalid identifier | Verify identifier on archive.org website |\n| **Slow download speeds** | Network throttling | Use `--limit-rate` with wget |\n| **Incomplete files** | Connection timeout | Use `wget -c` to resume |\n| **Missing files** | Format not available | Check available formats with metadata API |\n| **Checksum mismatch** | Corrupted download | Delete and re-download |\n| **Rate limiting** | Too many requests | Increase wait time between downloads |\n\n### Debug Mode\n\n```bash\n# Enable verbose output for troubleshooting\nexport CURATOR_DEBUG=1\n\ndownload_item_debug() {\n  local identifier=\"$1\"\n  local output_dir=\"$2\"\n\n  if [[ \"$CURATOR_DEBUG\" == \"1\" ]]; then\n    set -x  # Enable bash tracing\n  fi\n\n  # Get metadata with verbose curl\n  curl -v \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" 2>&1 | tee \"$output_dir\u002F.curator\u002Fmetadata-debug.log\"\n\n  # Download with verbose wget\n  wget --verbose \\\n       --debug \\\n       \"https:\u002F\u002Farchive.org\u002Fdownload\u002F$identifier\u002F\" \\\n       2>&1 | tee \"$output_dir\u002F.curator\u002Fdownload-debug.log\"\n\n  set +x\n}\n```\n\n## Performance Optimization\n\n### Parallel Download Tuning\n\n```bash\n# Optimal concurrent downloads based on connection speed\ndetermine_optimal_parallelism() {\n  local speed_mbps=\"$1\"\n\n  if [[ $speed_mbps -lt 10 ]]; then\n    echo 2  # Slow connection\n  elif [[ $speed_mbps -lt 50 ]]; then\n    echo 3  # Medium connection\n  elif [[ $speed_mbps -lt 100 ]]; then\n    echo 5  # Fast connection\n  else\n    echo 8  # Very fast connection\n  fi\n}\n\n# Test connection speed\ntest_connection_speed() {\n  # Download test file and measure speed\n  local test_file=\"https:\u002F\u002Farchive.org\u002Fdownload\u002Ftest_item\u002Ftest.mp3\"\n  local start_time=$(date +%s)\n\n  wget -q -O \u002Ftmp\u002Fspeed-test.tmp \"$test_file\"\n\n  local end_time=$(date +%s)\n  local duration=$((end_time - start_time))\n  local size=$(stat -c%s \u002Ftmp\u002Fspeed-test.tmp 2>\u002Fdev\u002Fnull || stat -f%z \u002Ftmp\u002Fspeed-test.tmp)\n  local speed_mbps=$(( (size * 8) \u002F (duration * 1000000) ))\n\n  rm \u002Ftmp\u002Fspeed-test.tmp\n\n  echo \"$speed_mbps\"\n}\n```\n\n### Caching Strategy\n\n```bash\n# Cache metadata to reduce API calls\ncache_metadata() {\n  local identifier=\"$1\"\n  local cache_dir=\".curator\u002Fcache\u002Fmetadata\"\n  local cache_file=\"$cache_dir\u002F$identifier.json\"\n\n  mkdir -p \"$cache_dir\"\n\n  # Check cache age\n  if [[ -f \"$cache_file\" ]]; then\n    local cache_age=$(( $(date +%s) - $(stat -c%Y \"$cache_file\" 2>\u002Fdev\u002Fnull || stat -f%m \"$cache_file\") ))\n\n    # Cache valid for 7 days\n    if [[ $cache_age -lt 604800 ]]; then\n      cat \"$cache_file\"\n      return 0\n    fi\n  fi\n\n  # Fetch and cache\n  curl -s \"https:\u002F\u002Farchive.org\u002Fmetadata\u002F$identifier\" | tee \"$cache_file\"\n}\n```\n\n## Summary\n\nArchive Acquisition skill provides:\n\n- **Discovery**: Search API patterns for finding content\n- **Quality Selection**: Automatic best-format selection (prefer FLAC, accept MP3 320K)\n- **Bulk Download**: Recursive wget and parallel download patterns\n- **Verification**: Checksum validation and integrity checks\n- **Collection Management**: Indexing, deduplication, incremental sync\n- **Integration**: Source plan generation for `\u002Facquire` command\n- **Performance**: Parallel tuning, caching, rate limiting\n\nUse this skill whenever working with Internet Archive content in the Media Curator framework.\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fhuman-authorization.md — Seek explicit authorization before bulk downloads and irreversible archive operations\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fresearch-before-decision.md — Evaluate archive item quality and metadata before committing to download\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Facquire\u002FSKILL.md — General acquisition skill that delegates to archive-acquisition for archive.org sources\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fintegrity-verification\u002FSKILL.md — Verify checksums after archive downloads\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fquality-filtering\u002FSKILL.md — Quality scoring used to select best format from archive items\n",{"name":5,"category":44,"namespace":45,"platforms":46,"description":7},"media-curator","aiwg",[47],"all","main","6754967c344ccb087a8de06972f55a41067b291b","agentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Farchive-acquisition",36,"https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg","https:\u002F\u002Faiwg.io","https:\u002F\u002Fgithub.com\u002Fjmagly","https:\u002F\u002Fintegrolabs.io","ml\u002Fai, industrial automation, safety\u002Fsecurity, ssi\r\n\r\nmagly.net\r\nintegrolabs.io\r\naiwg.io\r\nfortemi.com\r\npagenary.com\r\nbytecask.com","2026-11-14 02:10:01",{"source":8,"skillName":5,"commands":59,"prompt":69,"zipAvailable":70},[60,63,66],{"tool":61,"command":62},"npx","npx skills add jmagly\u002Faiwg --skill archive-acquisition",{"tool":64,"command":65},"bunx","bunx skills add jmagly\u002Faiwg --skill archive-acquisition",{"tool":67,"command":68},"pnpm","pnpm dlx skills add jmagly\u002Faiwg --skill archive-acquisition","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Farchive-acquisition\u002FSKILL.md",true,[72],{"path":73,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":76,"sourceHtmlUrl":77},"tools.sdn","OTHER","其他",797,"https:\u002F\u002Fgithub.com\u002Formastes\u002Fsimple\u002Fblob\u002Fmain\u002Fexamples\u002F05_stdlib\u002Fspipe\u002Fdoc\u002F00_llm_process\u002Fskill_command\u002Fskills\u002Fpipe\u002Fimpl\u002Fsstack\u002Ftools.sdn",[79,107,130,136,143,157],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":86,"publishedAt":39},"01M70QA0BSYJ49EES9V4RE8QH1","host-hardening","Read-only system hardening baseline and plan-first host hardening recommendations for SSH, Docker bind addresses, firewall persistence, datastores, exporters and audit retention.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[85],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106],"host","host hardening","hardening","read","re","recommendations","remediation","plan","port","verification","Bash","access","only","retention","audit","never","firewall","bind","secrets","request",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":117,"publishedAt":39},"01M70PNT2Z4HMZPRBTAF6073NN","exposure-analysis","Read-only firewall analysis and effective host exposure reconstruction for Docker published ports, UFW bypass, stale rules, CDN scope, IPv6 asymmetry and external probe allowlists.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fforensics\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[113,116],{"categoryNo":114,"categoryName":115,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[118,119,120,90,121,95,122,123,97,124,87,37,99,125,126,102,103,127,128,129],"exposure analysis","analysis","unknown","credentials","collection","ufw","ports","local","scope","reconstruction","operator","write",{"skillNo":131,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":135,"publishedAt":39},"01M70P8QATMPKA78E4FT5D2TNA","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[134],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[89,87,88,98,90,106,93,92,101,94,95,96,97,105,99,100,91,102,103,104],{"skillNo":137,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":142,"publishedAt":39},"01M70NMPVJ5H0JH131P60FW4R8","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fforensics-complete\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[140,141],{"categoryNo":114,"categoryName":115,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[119,118,102,121,95,122,97,120,87,37,99,125,126,90,103,124,123,127,128,129],{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":150,"publishedAt":39},"01M6CB4DDR0B4NNCFK7ZK7449H","fixture-skill","Exercise rule delivery.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Frule-delivery\u002Fskills\u002Ffixture-skill\u002FSKILL.md",[149],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[151,152,153,154,155,156],"fixture skill","fixture","rule","delivery","true","exercise",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":164,"publishedAt":39},"01M6CB4AVK1W76MFMPP0JP32CJ","pi-local","Pi-local duplicate-precedence fixture.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fproviders\u002Fpi\u002Fproject\u002F.pi\u002Fskills\u002Fpi-local\u002FSKILL.md",[163],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[165,166,125,167,152],"pi","pi local","duplicate"]