Repository navigation
Fix the follow-up defects from the PR #113 test plan - #115
Conversation
Four fixes found while running PR #113's manual test plan: the flaky rendered landing test, the resolve chain that never finds the loaded plugin, the untitled-course report folder, and T1 citations of T5 sources. The plan was dry-run end to end on a scratch copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use port 0 and the DevTools line on stderr, wait 30s, and fail at once with the exit code and last output when Chrome stops early. Mutation 50 guards the early-exit check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code replaces only the exact token ${CLAUDE_PLUGIN_ROOT} in skill
text and never sets it in the Bash shell. The ":-" form was never
replaced, so every skill ran the newest cached install, a stale one on
directory-marketplace and --plugin-dir setups. Check steps now print
STE_CHECK_MISSING with the path when that install has no checker.
Mutations 51a-51c guard the fix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
needs-analysis and course-import read project_name from the manifest before they write it, so a first run put the report in exports/untitled-course/. Take the slug from the session's course title, the same text the manifest step writes. Mutations 52a-52b guard the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Four skills cited [CogLoad-4] and [CogLoad-19] as T1, but references.md files both as T5, and course-builder gave two codes swapped tiers. The new test/check-citation-tiers.py reads each tier from references.md, and smoke-test runs it. Mutations 53a-53c guard the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a preamble rule for a checker error, remove two semicolons from new text, and warn when the course title placeholder is not replaced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e8eacd11f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # Do not read project_name from the manifest here. Step 7 writes it, so on a first run | ||
| # the manifest has no name yet and the report lands in exports/untitled-course/. | ||
| IFS= read -r _PROJECT_NAME <<'IDSTACK_PROJECT_NAME' | ||
| <project name> | ||
| IDSTACK_PROJECT_NAME |
There was a problem hiding this comment.
Preserve the existing project name on reruns
When needs-analysis runs against an existing manifest, this block always derives the export slug from the newly supplied/session title rather than the established project_name; step 7 then explicitly writes that title back. This conflicts with templates/manifest-schema.md, which says project_name must not be overwritten once set. If the user gives even a slightly different title on a rerun, future reports move to a new export folder while earlier reports remain under the old slug. Use the existing nonempty manifest value and fall back to the session title only during initial creation; the duplicated course-import block has the same problem.
Useful? React with 👍 / 👎.
| for code in CODE_RE.findall(line): | ||
| if code not in refs: | ||
| problems.append("%s: [%s] is not in evidence/references.md" % (where, code)) | ||
| for m in GROUP_RE.finditer(line): |
There was a problem hiding this comment.
Require every evidence code to have a tier
If a valid citation loses its tier—for example, [CogLoad-19] [T5] becomes [CogLoad-19]—this loop only confirms that the code exists, while GROUP_RE never matches the tierless citation. Because other citations keep cited nonzero, the checker exits successfully, allowing the exact required-tier invariant to regress. Track which code occurrences are consumed by a code-plus-tier group and report every unmatched occurrence.
Useful? React with 👍 / 👎.
Summary
This PR fixes four defects. idstack found them when it ran the manual test plan of PR #113. Each fix has a smoke check and a mutation case that puts the defect back and must fail.
CLAUDE_PLUGIN_ROOTin the shell of the Bash tool. It replaces only the exact text${CLAUDE_PLUGIN_ROOT}in skill text. The resolve chain used"${CLAUDE_PLUGIN_ROOT:-}", and Claude Code did not replace that text. So each$_IDSTACK/bin/...call used the newest install in the plugin cache, not the plugin that Claude Code loaded. All six copies of the chain now use the exact token. When the install has no checker, a check step now printsSTE_CHECK_MISSING: <path>. New preamble rules 5, 6 and 7 tell the skill what to do with each result. Mutations 51a–51c guard it.project_namefrom the manifest before they wrote it. On a first run, the report went toexports/untitled-course/. The other skills wrote toexports/<course-slug>/. The two skills now take the folder name from the course title of the session. If the model does not replace the title placeholder, the block printsPROJECT_NAME_NOT_SET. Mutations 52a–52b guard it.[CogLoad-4],[CogLoad-19]) as T1. One citation in course-builder had two tiers in the wrong order. The newtest/check-citation-tiers.pycompares each[Code-N] [Tn]citation withevidence/references.md, and smoke-test runs it. Mutations 53a–53c guard it.CLAUDE.mdnow gives 401 smoke assertions. The plan is indocs/superpowers/plans/2026-10-04-post-ste-followup-fixes.md.Changes that users see
--plugin-dirran the old cached copy. So this PR needs no release.IDSTACK_HOME. The documented order did not change. Before this PR, the first entry was always empty./Users/philippossavvides/github/idstackis behindmainand has nobin/idstack-ste-check. Until you rungit pullthere, check steps printSTE_CHECK_MISSING: /Users/philippossavvides/github/idstack. This result is intended.Verification
./test/smoke-test.sh./test/integration-test.sh./test/test-setup.sh./test/test-doctor.sh./test/test-status.sh./test/test-preamble-python.sh./test/test-extension.shpython3 test/test-ste-check.pypython3 test/check-citation-tiers.py ../test/mutation-test.shA reviewer examined each task. A review of the full branch followed, and a re-review examined its fixes.
Two parts ran only on macOS. They are the
DevTools listening online through thegoogle-chromewrapper, and theawk,sedandenv -ucalls in the new smoke block on GNU tools. The ubuntu CI logs of this PR are the check.Test plan
PASS: rendered landing page tests passandPASS: the substituted plugin root wins over a stale cache install.Results: 401/401.NOT guarded: 0.🤖 Generated with Claude Code