Skip to content

id(web): classify_tag treats any '.archive.' filename as an archive — notes.archive.txt renders with an 'archive: ?' badge, sorts out of the primary list, and links by hash instead of by name #2793

Closed

Description

@dezren39

id(web): classify_tag treats any '.archive.' filename as an archive — notes.archive.txt renders with an 'archive: ?' badge, sorts out of the primary list, and links by hash instead of by name

Evidence (main da42bfe7)

  • pkgs/id/src/web/routes.rs:165-169 (classify_tag): the archive branch returns FileKind::Archive for any name containing .archive., whether or not the suffix after it parses as a unix timestamp:

    if let Some(pos) = name.rfind(".archive.") {
        let ts_str = &name[pos + ".archive.".len()..];
        let ts = ts_str.parse::<u64>().ok();
        return (FileKind::Archive, ts);   // Archive even when ts is None
    }
  • The sibling auto- branch directly above it was fixed for exactly this flaw in id(web): classify_tag treats any 'auto-' filename as an auto-backup — auto-notes.txt renders with an 'auto: ?' badge and sorts out of the primary list #809/fix(id/web): classify_tag only treats auto-{ISO_DATE} names as auto-backups #810: it only returns FileKind::Auto when the remainder actually parses as an ISO date, and test_classify_tag_auto_prefix_non_date_is_primary (routes.rs:3119) pins that ordinary files like auto-notes.txt stay Primary. The archive branch never got the same treatment — test_classify_tag_archive_no_timestamp (routes.rs:3142) instead enshrines the loose behavior ("Even without a valid timestamp, .archive. pattern is recognized").

  • No producer creates a non-numeric archive suffix: archives are minted as {name}.archive.{unix-ts} (pkgs/id/src/fileops.rs:99-115, free_archive_name), and fileops itself documents "Archive tags are named <name>.archive.<unix-ts>; match the numeric …" (fileops.rs:413-415). A non-numeric suffix is therefore never a real archive.

Verified behavior (probe, laptop ~/git/fleet/probe-2026-10-30-laneA-archiveclass/)

classify_tag + parse_iso_timestamp copied verbatim from main, run over sample names:

notes.md.archive.1711000000         -> (Archive, Some(1711000000))   // genuine archive
notes.archive.txt                   -> (Archive, None)               // ordinary file
meeting.archive.notes               -> (Archive, None)               // ordinary file
backup.archive.draft                -> (Archive, None)               // ordinary file
x.archive.                          -> (Archive, None)               // empty suffix
photo.archive.2024-01-01            -> (Archive, None)               // date suffix, not a unix ts
auto-notes.txt                      -> (Primary, None)               // #809 control
my-document.md                      -> (Primary, None)

Why it matters

An ordinary user file whose name merely contains .archive. (a file about archives is the obvious case) is misrendered in the file list, in the same ways #809 fixed for auto-:

  • pkgs/id/src/web/templates.rs:239-245: it gets an archive: ? badge (parent ? when no primary shares its hash; a fabricated parent link when one coincidentally does).
  • templates.rs:308-310: its row links to /hash/{hash} instead of /edit/{name}.
  • routes.rs:897-916: it sorts after every primary file (timestamp unwrap_or(0)), and routes.rs:844-847 excludes it from hash_to_primary, so genuine auto/archive files sharing its hash lose their parent resolution and get_file_name (routes.rs:1027) won't prefer it.

Acceptance criteria

  • classify_tag returns FileKind::Archive only when the suffix after the last .archive. parses as a u64 unix timestamp; otherwise the name falls through to FileKind::Primary.
  • test_classify_tag_archive_no_timestamp is replaced with regression tests mirroring test_classify_tag_auto_prefix_non_date_is_primary: e.g. notes.archive.txt, meeting.archive.notes, x.archive. classify as Primary with no timestamp, while notes.md.archive.1711000000 still classifies as Archive with its timestamp.
  • Existing genuine-archive behavior is unchanged: rename/save archive naming (free_archive_name), sorting, badges, and parent resolution for numeric-suffix archives.

Dedup: #809/#810 cover the auto- prefix only; no open or recently closed issue covers the .archive. branch of classify_tag.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    source/creatorFiled by the new-issue-creator job
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    priority/lowNice to have; do when convenient
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    effort/xsTrivial: expected under 30 minutes of work
    work/self-assignedAn agent grabbed this item directly, outside the queue
    on Oct 30, 2026
  2. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  3. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  4. added a commit that references this issue on Oct 30, 2026
  5. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientsource/creatorFiled by the new-issue-creator jobtask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions