Skip to content

workspace: last-active frontmatter + checkpoint handoff, bump to v0.2.0 - #255

Open
fonta-rh wants to merge 10 commits into
openshift-eng:mainfrom
fonta-rh:worktree-workspace-last-active-frontmatter
Open

workspace: last-active frontmatter + checkpoint handoff, bump to v0.2.0#255
fonta-rh wants to merge 10 commits into
openshift-eng:mainfrom
fonta-rh:worktree-workspace-last-active-frontmatter

Conversation

@fonta-rh

@fonta-rh fonta-rh commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • last-active frontmatter: recent-projects.py now prefers an explicit
    last-active: YYYY-MM-DD field over unreliable filesystem mtime when
    ordering recent projects. The update-project, new-project, and
    close-project skills all write this field. Display count raised from 3
    to 5.

  • checkpoint handoff: New /workspace:checkpoint skill collapses the
    update-project/clearresume-project sequence into
    checkpoint/clear. A single-use JSON marker
    (<workspace>/.claude/handoff.json) is consumed by a SessionStart hook
    on the clear matcher, which emits a resume directive so the next session
    picks up automatically. Falls through to the existing recent-projects
    banner when no handoff is armed.

  • version bump: 0.1.2 → 0.2.0

Changes

File Change
scripts/recent-projects.py Prefer last-active frontmatter over mtime, display 5 projects
scripts/handoff.py new — write/read checkpoint marker (yaml-free)
tests/test_recent_projects.py new — 5 tests for last-active ordering
tests/test_handoff.py new — 18 tests for marker write/read/degradation
hooks/hooks.json Split SessionStart into matcher-scoped entries
skills/checkpoint/SKILL.md new/workspace:checkpoint
skills/{update,new,close}-project/SKILL.md Write last-active frontmatter
skills/resume-project/SKILL.md Skip task menu on handoff directive
CLAUDE.md, README.md Skill tables, layout, conventions
.claude-plugin/plugin.json Version 0.2.0

Test plan

  • python3 tests/test_handoff.py — 18 pass
  • python3 tests/test_recent_projects.py — 5 pass
  • python3 tests/test_skills.py — 36 pass
  • python3 tests/test_domain_info.py — 14 pass
  • bash tests/test_setup.sh — 84 pass
  • Linters clean (markdown, skills)
  • Live: /workspace:checkpoint/clear resumes automatically
  • Live: normal /clear shows recent-projects banner unchanged

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added /workspace:checkpoint to save the current project, next task, and reference files before /clear.
    • Projects can now resume automatically from a valid checkpoint.
    • Recent projects use last-active dates, fall back to filesystem activity, and display up to five projects.
    • New and updated projects track last-active activity.
    • Closing a project now clears its skills list.
  • Documentation

    • Updated workflow documentation for checkpointing, resuming, and activity tracking.
  • Tests

    • Added coverage for checkpoint handoffs and recent-project behavior.

fonta-rh and others added 5 commits August 4, 2026 10:42
Projects with a last-active: YYYY-MM-DD field in their CLAUDE.md
frontmatter now sort by that date instead of filesystem mtime.
Falls back to mtime for older projects without the field.

Also bumps the recent-projects display count from 3 to 5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The skill now sets last-active: YYYY-MM-DD on every update,
driving the SessionStart ordering hook.
New projects get last-active: YYYY-MM-DD (same as created) so the
SessionStart hook can order them from day one.
Closing a project stamps last-active to today, keeping the
SessionStart hook accurate through the project's full lifecycle.
@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: fonta-rh

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 4, 2026
@fonta-rh
fonta-rh marked this pull request as draft August 4, 2026 08:54
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The workspace plugin now tracks project activity with last-active, supports checkpoint handoffs across /clear, resumes checkpoint context, updates SessionStart routing, documents the workflow, adds standalone tests, and increments the plugin version to 0.2.0.

Changes

Workspace lifecycle

Layer / File(s) Summary
Project activity tracking
plugins/workspace/scripts/recent-projects.py, plugins/workspace/skills/{new-project,update-project,close-project}/SKILL.md, plugins/workspace/tests/test_recent_projects.py
Project ordering prefers valid last-active dates and falls back to filesystem mtime. Output shows up to five projects. Tests cover ordering, filtering, fallback, and formatting.
Handoff marker commands
plugins/workspace/scripts/handoff.py, plugins/workspace/tests/test_handoff.py
The new CLI writes, validates, expires, consumes, and reports one-time JSON handoff markers. Invalid or absent markers fall back to recent-project reporting.
Checkpoint and resume integration
plugins/workspace/skills/checkpoint/SKILL.md, plugins/workspace/skills/resume-project/SKILL.md, plugins/workspace/hooks/hooks.json
The checkpoint skill writes handoffs. Clear events read them. resume-project loads the recorded task and detail files.
Documentation and release metadata
plugins/workspace/README.md, plugins/workspace/CLAUDE.md, plugins/workspace/.claude-plugin/plugin.json, .claude-plugin/marketplace.json
Documentation describes the checkpoint workflow. The workspace plugin version changes from 0.1.2 to 0.2.0.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: ready-for-human-review

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ai-Attribution ⚠️ Warning AI use is stated in the PR, while seven PR commits use Co-Authored-By for Claude Opus and none use Assisted-by or Generated-by. Amend the PR commits to remove AI Co-Authored-By trailers and add the required Red Hat Assisted-by or Generated-by trailer.
✅ Passed checks (9 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Weak-Crypto ✅ Passed The feature-range diff adds no MD5, SHA1, DES, RC4, Blowfish, ECB, crypto API, custom cipher, or secret/token comparison; handoff equality checks validate metadata only.
Container-Privileges ✅ Passed The full PR diff adds no container/Kubernetes manifests and contains no privileged, host namespace, SYS_ADMIN, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed Changed scripts emit project/task/file metadata and paths only; no password, token, API key, PII, hostname, environment, marker, or traceback contents are logged.
No-Hardcoded-Secrets ✅ Passed Comprehensive scan of all modified and new files (handoff.py, recent-projects.py, test files, JSON configs, and skill definitions) found no hardcoded secrets, API keys, tokens, passwords, credentia...
No-Injection-Vectors ✅ Passed No injection vectors found. User input is validated (--project existence check), serialized safely (JSON), never executed (eval/exec/shell/os.system absent), and output only as formatted strings.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: last-active support, checkpoint handoff, and the version bump.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
plugins/workspace/scripts/recent-projects.py (1)

91-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename the overloaded "mtime" key to avoid future misuse.

The "mtime" key now stores either the real file mtime or an end-of-day timestamp derived from the last-active frontmatter date. A future reader of collect_projects() output could reasonably assume entry["mtime"] is always the actual file modification time, leading to a wrong assumption if that value is ever used for anything besides sorting.

Rename the key (for example, to "sort_ts") to make clear it is a sort key, not a literal mtime.

♻️ Proposed rename
         entries.append({
             "name": d.name,
             "type": fm.get("type", "—"),
             "status": fm.get("status", "—"),
-            "mtime": sort_ts,
+            "sort_ts": sort_ts,
             "date_str": date_str,
         })

-    entries.sort(key=lambda e: e["mtime"], reverse=True)
+    entries.sort(key=lambda e: e["sort_ts"], reverse=True)
     return entries
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/workspace/scripts/recent-projects.py` around lines 91 - 106, Rename
the `"mtime"` field created in `collect_projects()` to `"sort_ts"` (or another
clearly sort-oriented name), since it stores both file modification times and
last-active-derived timestamps. Update every consumer of the collected entry
field to use the renamed key while preserving the existing sorting behavior.
docs/superpowers/plans/2026-08-04-last-active-frontmatter.md (1)

270-312: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Plan documents a sort_source field that the shipped script omits.

This plan step defines collect_projects with a "sort_source" key on each entry, described in the Interfaces section (line 29) as existing "for testability." The reviewed recent-projects.py implementation does not add this key. Update the plan to reflect the final implementation, or add the field back if test coverage for sort_source was intended.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-08-04-last-active-frontmatter.md` around lines
270 - 312, The plan’s documented `sort_source` contract does not match the
shipped `collect_projects` implementation. Update the plan’s `collect_projects`
example and Interfaces description to remove the `sort_source` field and its
testability claim, unless the final implementation is intentionally expected to
expose it; keep the documentation consistent with the reviewed script.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/workspace/tests/test_recent_projects.py`:
- Around line 61-183: Add a negative test class alongside TestFallbackToMtime
that writes a project with a malformed last_active value and an older CLAUDE.md
mtime, plus a project without last_active and a newer mtime. Run the existing
run_hook flow and assert both projects remain in the systemMessage, with the
newer mtime-only project ordered before the malformed-date project, confirming
fallback to newest_mtime().

---

Nitpick comments:
In `@docs/superpowers/plans/2026-08-04-last-active-frontmatter.md`:
- Around line 270-312: The plan’s documented `sort_source` contract does not
match the shipped `collect_projects` implementation. Update the plan’s
`collect_projects` example and Interfaces description to remove the
`sort_source` field and its testability claim, unless the final implementation
is intentionally expected to expose it; keep the documentation consistent with
the reviewed script.

In `@plugins/workspace/scripts/recent-projects.py`:
- Around line 91-106: Rename the `"mtime"` field created in `collect_projects()`
to `"sort_ts"` (or another clearly sort-oriented name), since it stores both
file modification times and last-active-derived timestamps. Update every
consumer of the collected entry field to use the renamed key while preserving
the existing sorting behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 7f068d59-0235-4628-a025-970443e692a8

📥 Commits

Reviewing files that changed from the base of the PR and between bff4144 and d8c4395.

📒 Files selected for processing (6)
  • docs/superpowers/plans/2026-08-04-last-active-frontmatter.md
  • plugins/workspace/scripts/recent-projects.py
  • plugins/workspace/skills/close-project/SKILL.md
  • plugins/workspace/skills/new-project/SKILL.md
  • plugins/workspace/skills/update-project/SKILL.md
  • plugins/workspace/tests/test_recent_projects.py

Comment thread plugins/workspace/tests/test_recent_projects.py
fonta-rh and others added 2 commits August 4, 2026 11:26
Collapses the update-project → /clear → resume-project sequence into
checkpoint → /clear by writing a single-use marker that a SessionStart
hook consumes on the next clear.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fonta-rh fonta-rh changed the title workspace: order recent projects by last-active frontmatter workspace: last-active frontmatter + checkpoint handoff, bump to v0.2.0 Aug 4, 2026
Add negative test for malformed last-active fallback to mtime.

Co-Authored-By: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fonta-rh

fonta-rh commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Addressed CodeRabbit review-body findings:

  • mtimesort_ts rename (recent-projects.py:91-106): Won't fix — the key is internal to collect_projects and its two callers. Renaming adds churn for no correctness gain.
  • Plan documents sort_source (plan doc:270-312): Won't fix — the plan is a historical development artifact that captured intent at planning time; the implementation intentionally diverged during review. Plans are not kept in sync post-implementation.

@fonta-rh
fonta-rh marked this pull request as ready for review August 4, 2026 09:37
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 4, 2026
Development artifact — not part of the shipped plugin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/workspace/.claude-plugin/plugin.json`:
- Line 5: Update the workspace entry in the marketplace configuration to version
0.2.0 so it matches the version declared by the plugin manifest.

In `@plugins/workspace/scripts/handoff.py`:
- Around line 150-155: Update the project validation around project_dir to
reject absolute project names and any path containing .. components, then
canonicalize the candidate path and confirm it remains within the canonical root
/ "projects" directory before allowing the handoff. Preserve the existing error
response for invalid or nonexistent projects.
- Line 56: Resolve the Ruff findings by adding narrow, reasoned noqa annotations
without changing behavior: at plugins/workspace/scripts/handoff.py:56 suppress
S606 for the fixed Python executable and script; at
plugins/workspace/scripts/handoff.py:226 suppress BLE001 using the existing
SessionStart boundary rationale; and at
plugins/workspace/tests/test_handoff.py:30-34, 44-48, and 250-253 suppress S603
for each controlled test subprocess.
- Around line 89-90: Update the marker deletion flow around unlink_quietly so it
returns whether removal succeeded, and have the caller return None when the
consumed marker cannot be removed. Preserve the marker return only after
successful deletion to maintain the single-use contract.
- Around line 110-112: Update the load_files validation before the return in the
data-loading flow to require both a list value and string type for every
element. Treat any non-list or mixed/non-string list as the invalid marker so
the existing fallback path runs and build_directive() never receives invalid
values; preserve valid lists of strings unchanged.
- Around line 158-165: Constrain checkpoint load paths to the project directory:
in plugins/workspace/scripts/handoff.py lines 158-165, reject absolute paths and
any .. components when constructing load_files, and resolve plus revalidate each
marker path beneath P.dir immediately before the Read tool uses it. Update the
corresponding path-handling guidance in
plugins/workspace/skills/checkpoint/SKILL.md lines 48-60 and
plugins/workspace/skills/resume-project/SKILL.md lines 146-154 to require the
same project-directory validation.

In `@plugins/workspace/skills/checkpoint/SKILL.md`:
- Around line 1-5: Update the checkpoint skill frontmatter to use a
colon-namespaced <domain>:<action> name and add the minimal allowed-tools
declaration for this workflow, including Skill and Bash; preserve the existing
description, argument hint, and invocation setting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: c9a5faa8-c9db-468d-86f8-95f9b140a89a

📥 Commits

Reviewing files that changed from the base of the PR and between d8c4395 and dd34354.

📒 Files selected for processing (8)
  • plugins/workspace/.claude-plugin/plugin.json
  • plugins/workspace/CLAUDE.md
  • plugins/workspace/README.md
  • plugins/workspace/hooks/hooks.json
  • plugins/workspace/scripts/handoff.py
  • plugins/workspace/skills/checkpoint/SKILL.md
  • plugins/workspace/skills/resume-project/SKILL.md
  • plugins/workspace/tests/test_handoff.py

Comment thread plugins/workspace/.claude-plugin/plugin.json
Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/skills/checkpoint/SKILL.md
The plugin.json bump was not reflected in the root marketplace manifest.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai coderabbitai Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Aug 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/workspace/scripts/handoff.py`:
- Around line 81-90: Update the marker handling flow around the
path.is_file/read_text logic to atomically rename handoff.json to a unique
claimed filename in the same directory before reading; only the process that
wins the rename should parse and emit the directive, and the claimed file must
be removed in a finally block. Add a concurrent read regression test in
test_handoff.py asserting exactly one process emits “Checkpoint handoff
pending.”
- Around line 168-171: Harden the marker-write flow around marker_path by
canonicalizing and validating the workspace path, rejecting traversal and
symlinked .claude or handoff.json components before writing. Replace
mkdir/write_text with no-follow directory and file operations that cannot follow
symlinks, and add a regression test covering redirected marker writes.

In `@plugins/workspace/tests/test_recent_projects.py`:
- Line 29: Add narrow `# noqa: S603` annotations to the `subprocess.run` calls
at the two reported locations in `test_recent_projects.py`, documenting that
each is a controlled repository-local test boundary using `sys.executable`
without a shell. Do not disable S603 globally or alter the subprocess behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: d1ac03e7-4bfe-4d04-a0e4-05f53b047456

📥 Commits

Reviewing files that changed from the base of the PR and between bff4144 and 042a223.

📒 Files selected for processing (14)
  • .claude-plugin/marketplace.json
  • plugins/workspace/.claude-plugin/plugin.json
  • plugins/workspace/CLAUDE.md
  • plugins/workspace/README.md
  • plugins/workspace/hooks/hooks.json
  • plugins/workspace/scripts/handoff.py
  • plugins/workspace/scripts/recent-projects.py
  • plugins/workspace/skills/checkpoint/SKILL.md
  • plugins/workspace/skills/close-project/SKILL.md
  • plugins/workspace/skills/new-project/SKILL.md
  • plugins/workspace/skills/resume-project/SKILL.md
  • plugins/workspace/skills/update-project/SKILL.md
  • plugins/workspace/tests/test_handoff.py
  • plugins/workspace/tests/test_recent_projects.py
🚧 Files skipped from review as they are similar to previous changes (10)
  • plugins/workspace/hooks/hooks.json
  • plugins/workspace/skills/checkpoint/SKILL.md
  • plugins/workspace/.claude-plugin/plugin.json
  • plugins/workspace/CLAUDE.md
  • plugins/workspace/README.md
  • plugins/workspace/skills/update-project/SKILL.md
  • .claude-plugin/marketplace.json
  • plugins/workspace/scripts/recent-projects.py
  • plugins/workspace/skills/resume-project/SKILL.md
  • plugins/workspace/skills/close-project/SKILL.md

Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/scripts/handoff.py
Comment thread plugins/workspace/tests/test_recent_projects.py
@fonta-rh

fonta-rh commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Addressed CodeRabbit review-body findings:

  • recent-projects.py:91-106 — Rename "mtime" key to "sort_ts": Won't fix — style nit; key is internal to one file with no external consumers.
  • plan doc:270-312 — Plan documents sort_source not in code: Won't fix — plans are working documents; divergence from final implementation is expected and normal.

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant