- Problem: main d30588f9 (integrate-reviewed-followups) added a skill and
bumped the skill-triggers registryDigest, conflicting with this branch's
own digest refresh for the plan-orchestrate SKILL.md edit.
- Fix: take main's manifest and recompute registryDigest over the merged
tree via scripts/lib/context-pack-registry.js; triggers, triggersDigest
and generatedAt untouched.
- Verification: environment reproduces both sides' committed digests on
their own trees; merged-tree digest a6b6bce7...; validate-context-profiles
293 skills OK; plan-orchestrate registry fixtures 8/8; full
node tests/run-all.js = 704 passed / 0 failed.
Add metadata.upstream: tinystruct==1.7.34 to both the English skill and
its Japanese translation, so a future sync can mechanically diff the
pinned version against the current tinystruct release instead of
rediscovering drift from prose. Also migrates the legacy top-level
`origin: ECC` key into the metadata block, matching the schema used by
the rest of the skills in this repo (tests/commands/learn-skill-discovery.test.js
already asserts top-level `origin:` is unsupported).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Problem: the registry fixtures validated SKILL.md against the committed docs/COMMAND-REGISTRY.json but nothing in the file asserted the registry itself was fresh, so a standalone run passed against a stale registry (npm test does run command-registry:check first, but this file is also run on its own).
- Fix: rebuild the registry in memory via the exported generateRegistry() and assert deep equality with the committed JSON so drift fails as a regenerate hint with a field diff instead of passing silently; add one sentence to SKILL.md stating that a command retired from commands/ fails closed with the BLOCKED marker like a no-argument command.
- Verification: node tests/skills/plan-orchestrate-registry.test.js passes with the new check 8 (8/8); sabotage with a mutated registry description fails check 8 with the regenerate hint and a field diff.
Preserve the original contributor histories and apply the exact independently reviewed repair.
Source-Parent: edcb389e2c
Review-Manifest-SHA256: c607db261fe8760465af1dffd5f9a3dda42478c5f745dbfa5916fd8e014ef306
Preserve contributor name changes, update carrier expectations, and bind the existing manually curated trigger seed to the actual registry.
Source-PR: https://github.com/affaan-m/ECC/pull/3059
Source-Head: 8115a5e46c
Reviewed-Manifest-SHA256: 6295aa042be428a2f3f9fc5a120a0e5a26a9548e1d53e17a3b20febe9baa1fdc
Reject reserved device names (including with extensions and the
superscript COM/LPT variants), trailing dots or spaces, and colon
stream syntax on every platform, and execute the documented snippet
in a regression test.
Review caught this on the note added last commit, and it was right again. `sync`
prints the card's path relative to the repository root; a Markdown image
resolves relative to the file it sits in. Telling the agent to reuse the
printed path is correct only for a README at the root.
Verified: with output `docs/usage.svg`, sync prints `./docs/usage.svg`. Pasted
into `docs/zh-CN/README.md` that resolves to `docs/zh-CN/docs/usage.svg` — the
card exists, the image is broken. The nested README needs `../usage.svg`.
The note now says to rewrite the path for the target file and gives both forms.
Review caught this on the previous commit, and it was right. `sync` resolves
its target as `--out` if given, otherwise `.tokenchit.json`'s `output` —
`tokenchit.svg` is that field's default, not a fixed location. Saying the bare
command "writes tokenchit.svg in the repository root" is wrong for anyone who
has configured another path.
Checked rather than assumed: a config with `output: docs/custom-card.svg` makes
the bare command report `would write docs/custom-card.svg`.
Three places said it. Step 3 now says the configured output, the flag table no
longer implies the default is fixed, and the README snippet carries a note to
use the path sync actually reported. The command's usage comment says the same.
The workflow's step 3 was an executable block containing placeholders:
npx -y @tokenchit/cli@0.10.0 sync [--out PATH] [--theme auto|light|dark] [--dry-run]
Copied as written, that does not fail. `sync` ignores an unrecognised
positional argument rather than refusing it, and `[--dry-run]` is positional —
so the brackets are discarded and a real sync runs. Verified against the
published 0.10.0: the literal command exits 0 and writes tokenchit.svg, 10,144
bytes, while `--dry-run` spelled properly writes nothing. An agent following
this skill for a preview would have changed the working tree.
Step 3 now shows one bare runnable command and moves the options into a table,
so nothing inside a bash block is a placeholder. Three reviewers flagged this
shape — it was the standing merge-risk note on the PR — and it was still live.
Also states the Node floor. The skill said only "Requires Node.js"; the package
declares engines node >=22, so anyone on 20 met a confusing failure instead of
a clear precondition.
The conflicts were all counter bumps. Upstream moved 286 -> 292 skills while
staying at 94 command shims; this branch adds one of each, so the merged values
are 293 skills and 95 shims, carried across the English, Turkish and Chinese
docs. Upstream's 2.2.2 version is kept.
One line needed care and nearly went wrong: the v2.0.0 changelog entry records
"281 skills, 67 agents, 94 command shims". That 94 is a fact about a past
release, not a live counter, and a blanket substitution had rewritten it. It is
back to 94. The Discord snowflake and the Perl badge colour both contain "94"
too and are untouched.
While here, the pin was stale. It named 0.7.0, three minor versions behind, so
anyone installing through this skill got a tool without Gemini support, the
read-only doctor report, PNG export or the portable ledger. Raised to 0.10.0 —
knowingly, which is what the skill's own note asks for — and the documented
`npm view @tokenchit/cli@0.10.0 dist.integrity dist.tarball` was run to confirm
it resolves.
The agent list was stale for the same reason: Gemini CLI became a real adapter
in 0.9.0 and the skill still advertised three agents. Verified against the
published 0.10.0 tarball rather than from memory — `init --help` and `doctor`
both name Claude Code, Codex, Gemini CLI and OpenCode.
Two overlapping first payOnce calls could both pass the session-cap check
while sessionSpent was still 0, then both increment after the confirm await,
exceeding SESSION_CAP. Reserve MAX_AMOUNT before any await and release it
only when the user declines. Mirrored in ja-JP and zh-CN.
Sync skills/tinystruct-patterns against tinystruct's own canonical copy of
this skill (.agents/skills/tinystruct-patterns/), which the framework repo
keeps up to date with each release:
- Document the bin/dispatcher / bin/dispatcher.cmd launcher generation
workflow (never hand-write or copy it; the framework generates it via
ApplicationManager.init()).
- Add native MCP server/tool integration (org.tinystruct.mcp.*), including
the prompt-injection warning for tool return values and overloaded-tool
schema merging.
- Add annotation-based DB mapping (@Table/@Id/@Column) alongside XML
mapping, the --mapping annotation generator flag, and table
auto-creation via database.autocreate.
- Add the programmatic logging/diagnostics subsystem (ANSI console colors,
StackWalker-based caller tracing, per-package level overrides).
- Update the architecture package map accordingly.
Also update the Japanese translation (docs/ja-JP/skills/tinystruct-patterns)
to match, which had drifted to an older, condensed version of this skill.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(skill-comply): stop a failed step supplying evidence downstream
`_check_temporal_order` fell back to the raw classifier output whenever
the referenced step was absent from `resolved`. A step only enters
`resolved` once it passes, so "failed" and "not graded yet" were the
same thing to that lookup, and a dependant could pass on an event
belonging to a prerequisite that had failed its own ordering check.
With three steps C, A (before C) and B (after A) and events C@T0,
A@T1, B@T2, A fails and B passed on A's classified event: 2/3 instead
of 1/3. It compounds down a chain, so one failed prerequisite could
leave a five-step workflow reading 4/5.
The grader now tracks which steps have been graded at all. A referenced
step that was graded and is missing from `resolved` failed, and its
events are refused with a reason that says so. A step not graded yet is
a forward reference to a step declared later, and the fallback stays as
it was: that is what makes an out-of-order declaration work, and the
existing regression for it goes red if the fallback is removed instead.
`before_step` deliberately keeps the old fallback. The two fail in
opposite directions: an `after_step` fallback can only turn a failure
into a pass, a `before_step` one can only turn a pass into a failure,
so dropping it would relax a constraint because some other step failed.
* fix(skill-comply): revoke a pass that rested on a later-failing prerequisite
Review of #3109 found the mirror image of the case that PR fixes. `graded`
only catches a prerequisite that had already failed when its dependant was
graded. A step declared *before* its `after_step` is graded against the
classifier's raw events for a step that has not run yet — the fallback that
makes an out-of-order declaration work — and nothing revisited it once that
step went on to fail its own checks.
Add a pass after grading that demotes any detected step whose `after_step`
ended up failing, repeated to a fixed point: one demotion can invalidate
whatever depended on it, in either declaration order. Demotion only removes
passes, so it terminates. `compliance_rate` is computed from the demoted
results.
Also from review: build `graded` and the chain test's step list as new
objects rather than mutating (AGENTS.md immutability rule), and annotate the
injected mocks in the tests this PR owns.
The temporary HTTP server that export-pdf.sh spins up to render a deck
joined the decoded request path onto SERVE_DIR without checking the
resolved path, and listened on all interfaces. A request such as
`/..%2f..%2f..%2fetc%2fpasswd` (raw, or issued by a malicious deck via
fetch() while it renders) returned files outside the deck directory, and
any host on the network could hit the port while an export was running.
- resolve the decoded path against SERVE_ROOT and answer 403 when the
result is not inside it (handles ../, %2e%2e, %2f and query strings)
- answer 400 on malformed percent-encoding instead of throwing
- listen on 127.0.0.1 only; the only client is the local headless browser
Verified with raw HTTP requests against the handler: `/` and
`/index.html` -> 200, `/../x`, `/..%2f..%2fx`, `/%2e%2e/x`,
`/deck/../../x` -> 403, unknown file -> 404, `/%zz` -> 400, and
server.address() reports 127.0.0.1.
Fixes#3101