From b26a991cd02d0d41f78d38be8d82ba1ddad2e1f9 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Tue, 9 Jun 2026 03:36:57 -0700 Subject: [PATCH] feat!: Adopt explicit-UTC second-precision timestamps for KB date fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KB assertion date fields and event capture timestamps are now stored as explicit-UTC second-precision timestamps (`YYYY-MM-DDTHH:MM:SSZ`) sourced from a single authoritative clock, replacing the previous date-only form. Frontmatter validation accepts both the timestamp form and the legacy bare `YYYY-MM-DD` form, so date-only notes already in existing stores stay valid; this dual-accept policy is permanent, not a migration window. Notes written by `kb-add` derive their creation, update, and verification dates from one instant, so a note can no longer be born already marked verified before it was created. The `--last-verified` flag is removed: an agent can no longer supply a verification date from its own clock, which near the UTC-midnight boundary could disagree with the writer's clock and produce a verified-before-created record. Passing the flag now reports an unknown-flag error. Staleness detection and freshness ranking are unchanged in granularity — both date forms resolve to identical whole-day ages — while a stored value matching neither form now yields no age rather than a best-effort, possibly wrong one. Malformed values, including a timestamp missing the `Z` marker, an offset form, an unreal calendar date, or an unreal clock time, are rejected. Because a freshly added note now always carries a verification date, adding the first note to a vault that previously had none enables vault-wide verification-staleness checks: `kb-curate` then surfaces older notes lacking a verification date as re-verification candidates. --- .../agents/content/skills/kb-add/SKILL.md | 17 ++-- .../agents/scripts/bundle-skill-helpers.ts | 25 +++--- .../src/capture-event/__tests__/cli.test.ts | 4 +- packages/agents/src/capture-event/cli.ts | 3 +- .../agents/src/kb-add/__tests__/cli.test.ts | 12 +-- .../src/kb-add/__tests__/prepare-note.test.ts | 30 ++------ packages/agents/src/kb-add/cli.ts | 5 +- packages/agents/src/kb-add/prepare-note.ts | 18 ++--- packages/agents/src/kb-add/types.ts | 4 +- .../agents/src/kb-edit/__tests__/cli.test.ts | 2 +- .../operations/__tests__/append.test.ts | 2 +- .../operations/__tests__/bump-updated.test.ts | 2 +- .../operations/__tests__/retag.test.ts | 2 +- .../__tests__/supersede-with.test.ts | 4 +- .../operations/__tests__/verify.test.ts | 19 ++++- .../agents/src/kb-edit/operations/append.ts | 8 +- .../src/kb-edit/operations/bump-updated.ts | 14 ++-- .../agents/src/kb-edit/operations/retag.ts | 4 +- .../src/kb-edit/operations/supersede-with.ts | 4 +- .../agents/src/kb-edit/operations/verify.ts | 4 +- .../kb-shared/__tests__/note-helpers.test.ts | 52 ++++++++++--- packages/agents/src/kb-shared/note-helpers.ts | 20 +++-- packages/kb/src/create/render-seeds.ts | 3 + .../fixtures/parity/expected-findings.json | 2 +- .../rules/__tests__/frontmatter-rule.test.ts | 77 +++++++++++++++++++ packages/kb/src/rules/frontmatter-rule.ts | 35 ++++++--- packages/kb/src/types.ts | 4 +- 27 files changed, 254 insertions(+), 122 deletions(-) diff --git a/packages/agents/content/skills/kb-add/SKILL.md b/packages/agents/content/skills/kb-add/SKILL.md index d2e23704..7cec742d 100644 --- a/packages/agents/content/skills/kb-add/SKILL.md +++ b/packages/agents/content/skills/kb-add/SKILL.md @@ -14,14 +14,13 @@ The split is deliberate: the helper is narrow and mechanical; the classification ## Arguments -| Argument | Description | Required | -| ----------------- | --------------------------------------------------------------------------------------- | -------- | -| `--diataxis` | The note's Diátaxis label (e.g. `howto`, `concept`, `reference`, `tutorial`). | No | -| `--title` | The note title; also doubles as the filename. | Yes | -| `--kb` | Explicit knowledge base name; overrides the discovered `.kb/` and the registry default. | No | -| `--folder` | KB-relative folder under which to write the note. Defaults to the KB root. | No | -| `--tags` | Comma-separated tag list. Known aliases are canonicalized at write time. | No | -| `--last-verified` | `YYYY-MM-DD` date the note's claims were last verified. | No | +| Argument | Description | Required | +| ------------ | --------------------------------------------------------------------------------------- | -------- | +| `--diataxis` | The note's Diátaxis label (e.g. `howto`, `concept`, `reference`, `tutorial`). | No | +| `--title` | The note title; also doubles as the filename. | Yes | +| `--kb` | Explicit knowledge base name; overrides the discovered `.kb/` and the registry default. | No | +| `--folder` | KB-relative folder under which to write the note. Defaults to the KB root. | No | +| `--tags` | Comma-separated tag list. Known aliases are canonicalized at write time. | No | A value-bearing flag accepts both `--diataxis howto` and `--diataxis=howto`. The note body is read from stdin to EOF; an empty body is allowed when a stub note is appropriate. @@ -79,7 +78,7 @@ Pipe the composed body to the bundled helper. A heredoc keeps multi-line bodies cat <<'EOF' | node "$(dirname "$SKILL_PATH")/kb-add.mjs" \ --diataxis