Preserve full contributor history and current catalog. Actual process workflows cover concurrency, recovery, sprint planning and read-only status. Bound registry symlinks, counts and lock waits; preserve manually curated trigger provenance.
- questionIdsFor and condensedHintFor take an optional
{ externalContract: true }; without it a code change that handles data
asks data-schema only, and an unknown profile gets the original four
questions and condensed hint.
- The hook reads GATEGUARD_EXTERNAL_CONTRACT_QUESTION with the same
spellings as GATEGUARD_METRICS and passes it to the full denial, the
condensed denial and the metrics record, so all three agree.
- The effectiveness harness's arm patch forwards the option, so an arm
never drops it silently.
Docs: change-profile.md gains an External-contract question section and
qualifies "byte-identical to the fixed four questions"; design-notes.md,
SKILL.md (switch table, data rule, word-for-word set) and CHANGELOG say
the fifth question is opt-in; question-effectiveness.md and the harness
README note that the runner clears GATEGUARD_* variables, so a gate arm
from a current tree measures the gate without the question.
skill-triggers@1.json: registryDigest refreshed for the SKILL.md body
change; the description and triggers are unchanged.
- design-notes.md: new Type filters and Path patterns sections; Search
scope extends the search-of-the-target rule to name lookups; Flag
parsing lists the new value flags.
- change-profile.md: Unicode line terminators make an edit non-trivial.
- skills/gateguard/SKILL.md and CHANGELOG.md describe the same rules.
- skill-triggers@1.json: refresh registryDigest for the SKILL.md body
change. The skill's description is unchanged, so triggers and
triggersDigest are untouched, as in the plan-orchestrate refresh.
Resolve six conflicts:
- hooks/hooks.metadata.json: keep this branch's gateguard description and
fingerprint, add upstream's hookify-runtime entries.
- package.json: keep both gateguard-report.js and github-coordination.js.
- scripts/hooks/gateguard-fact-force.js, tests/hooks/gateguard-fact-force.test.js,
skills/gateguard/SKILL.md: upstream added a simpler session denial cap; this
branch already has the fuller one (cap threaded through
markCheckedAndCountDenial, malformed-value warning, miss and target notes),
so keep it. Upstream's taskset and su wrapper handling, fail-closed
recursion limit and soft-hyphen sanitising merged cleanly and their tests pass.
- manifests/context-packs/skill-triggers@1.json: take upstream's file and
recompute registryDigest for the merged registry.
Treat non-2xx activity responses as feed errors, preserve non-Markdown Copilot agent assets, and apply the reviewed reference escape parity correction with regenerated bindings. Allow the test runner to drain piped output on its existing success or failure exit status. Validate installed workflows and bounded real Node20/24 pipe regressions.
Resolve the one conflict, skill-triggers@1.json: take upstream's
pretty-printed manifest and recompute registryDigest for the merged
registry so validate-context-profiles passes.
Carry forward PR #3055 at 92f53c4c onto ef648e01, preserving contributor attribution and current main. Focused maintainer fixes reuse shared input ceilings, preserve late root context through outer bootstrap, bound frontmatter before immutable parsing, and assert real oversized input in the limits workflow.
Preserve PR #2968 contributor history, verified upstream claims, and target-specific metadata. Rebind the existing trigger registry metadata after the merge, retaining current trigger phrases and generation provenance. Portable Bun 1.4.2 isolation and parallel-timing examples passed; all five Markdown files and context profiles validated.
Phase 1 pipes the build into `tail -20`. Without pipefail the pipeline's
exit status is tail's, so a failed build exits 0. Phase 2 already sets
pipefail, but only after Phase 1 has run, and each phase is its own code
block. Set it at the top of the Phase 1, 3 and 4 blocks, which pipe a gate
into head or tail. Mirrored in pi/core.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A non-numeric, negative, or exponent Points value was persisted and
silently skewed the derived sprint total (bogus -> 0, -3, 1e3 -> 1000)
with no drift reported. parseStory now enforces the documented values,
so apply rejects the batch and status reports the invalid story.
Resolve the Greptile findings on 74262955:
- Refuse symlinked .stories/, epics/, sprints/, .txn/, .ids/ and
symlinked ledger files, so no read or write leaves .stories/.
- Recovery accepts only regular backup-<n> files in .txn/, validates the
whole journal before restoring, and never writes through a planted
restore.tmp.
- Remove a stale lock only under .lock.break after a re-read, so a live
lock is never deleted; a leftover .lock.break times out (exit 3)
instead of spinning.
- apply enforces one-step-forward status transitions, new stories start
as todo, and Sprint must be unassigned or an existing sprint file.
- Refuse a batch that names the same file twice (e.g. a\b vs a/b).
Symlink tests skip on Windows when symlink creation returns EPERM.
Brings in the three commits main gained since the branch's merge base: the 2.2.3
release, retiring the Everything Claude Code name for ECC, and the ja-JP sponsor
update. 227 files arrive from main; two conflicted.
CHANGELOG.md: the branch had added an Unreleased section and main a released
2.2.3 section, both at the top. Both are kept verbatim with Unreleased above
2.2.3, since none of the branch's entries shipped in that release.
manifests/context-packs/skill-triggers@1.json: both sides had recomputed
registryDigest from the same earlier value to different results, and neither is
the digest of the merged tree. It is recomputed with loadContextRegistry over the
merged tree and only that field changes; triggers and triggersDigest are
untouched on both sides. validate-context-profiles passes.
All twelve CI validators pass. The full suite reports 44 failures in seven files;
43 of them fail by name and count identically on an unmodified upstream/main, and
the remaining one, plugin-hook-bootstrap, fails only inside run-all and passes in
isolation on both trees. The merge introduces no failing test that main does not
already have.