Repository navigation
Conversation
A card's Working on is written once at onboarding and rarely touched, so a
six-month-old list tells visitors and AI agents what someone did last spring.
Nothing recorded when it last changed, so nothing could say it was old.
- cards migration 0033 (expand-only, NOT applied anywhere): nullable
agent_profile_cards.working_on_updated_at plus a BEFORE INSERT/UPDATE OF card
trigger that stamps it whenever card->'working_on' changes and mirrors it into
the card JSON. A trigger because the list is also written in SQL
(s10_save_section, companion_save_fields), where cards-api cannot add a key;
the column is the authority, so a stale copy of the card JSON cannot move it.
No backfill: existing rows stay NULL = unknown = never stale.
- cards-api: STALE_DAYS=90 rule (services/stale_signals.py); live is_working_on
memory facts count as fresh; owner-only POST
/cards/by-handle/{handle}/working-on/confirm (401 unsigned, 403 non-owner,
503 until 0033 is applied); one "Working on" row in the morning digest.
- cards-web: dimmed chips + "Not updated in 3+ months" on classic and edition
cards, "Still working on this? Confirm · Update" for the owner, and
zynd:working_on_updated_at in data.json.
- Behind FEATURE_STALE_SIGNALS / NEXT_PUBLIC_FEATURE_STALE_SIGNALS, both off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
Superseded by #140, which combines all five features with fixes from a four-way review. The branch is kept. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Signals rot. A card's Working on is written once at onboarding and rarely touched, so a six-month-old list keeps telling visitors and AI agents what someone was doing last spring. Beacons already expire after 7 days; Working on had no freshness signal at all, because nothing recorded when it last changed.
What
cards.agent_profile_cards.working_on_updated_atand aBEFORE INSERT OR UPDATE OF card, working_on_updated_attrigger that stamps it whenevercard->'working_on'changes and mirrors it intocard->'working_on_updated_at'.cards.s10_save_section(editor section saves) andcards.companion_save_fields(the browser extension) only accept fixed key lists, so cards-api cannot add a stamp key there without a racy second write. The trigger covers every writer: publish/republish upsert, editor full-card PATCH, beacons, both RPCs, memory refresh, and anything run by hand.working_onunchanged keep the stamp. An explicit column write (the confirm) is kept, and is clamped so it can never be in the future.services/stale_signals.py:STALE_DAYS = 90.working_on_is_stale()is true only when the list is non-empty, the stamp is known, and the stamp is at least 90 days old.services/signals.py: liveis_working_onmemory facts are merged into the public list, so the public stamp moves up to the newest of them (capped at now).POST /cards/by-handle/{handle}/working-on/confirm: owner-only, using the existing_principal/_owner_emailJWT pattern. It returns 401 unsigned, 403 for a non-owner, 404 for an unknown card or flag off, and 503 before 0033. It writes only the column and does not change the list.working_on_updated_atfield is added toAgentProfileCardandCardView. It is omitted from the dump when unknown, so legacy cards are stored byte-identical.services/digest.py): when the owner's public Working on is stale, it adds one "Working on" row, "Still working on this? … Confirm / Update it", in both plain text and HTML, built with the existing_label/_box/_rowhelpers. Confirm needs the owner's session, so it links to their card (/p/<handle>#working-on), where the button is. Update links to/p/<handle>/edit#signals. Nothing else in the digest changes: subject, preheader and intro are untouched.router.refresh(). It is an event handler, not an effect.data.json: addszynd:working_on_updated_atwhen known, so AI clients can judge freshness. This is additive only.Flags (both default off)
FEATURE_STALE_SIGNALSNEXT_PUBLIC_FEATURE_STALE_SIGNALSzynd:working_on_updated_atin data.jsonNot flagged (my choice): the DB stamping, and the
working_on_updated_atfield in cards-api's card JSON responses (/cards/by-handle/*,/view,/mine). Both are harmless and additive, and the field only has a value once 0033 is applied. Gating the stamp would mean losing history until the flag flips.Migration and rollback
packages/db/cards/migrations/0033_stale_working_on.sql(-- owner: cards, generated bycards:generate, then the trigger appended, with journal and snapshot). It is expand-only, and cards-api tolerates it being applied before or after the deploy.There is no staging DB, so applying it is live in prod. Please review and apply per
packages/db/README.mdstep 6.Test evidence
pytest -qtest_x_bot.py), 23 skippedSTALE_TEST_DATABASE_URL)tests/test_stale_working_on_postgres.pyon local disposable Postgres 15npm run lintnpx tsc --noEmitnpm run build(flag on)src/lib/stale-signals.test.ts(tsx --test)db:lint,db:check,typechecknpm testwithCARDS_TEST_DATABASE_URL(local)packages/db/test/cards-stale-working-on-sql.test.ts, run on the full history on a local Postgres, covers these cases:s10_save_section: another section keeps the stamp, the Working on section restampscompanion_save_fieldsrestampsnext devagainst a mock API:Not verified
PGRST204or42703; both are handled as 503.🤖 Generated with Claude Code