mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-14 08:59:01 +02:00
feat(bin): gstack-design-detect wrapper + design_detector config key
bin/gstack-design-detect.ts finds and runs an impeccable engine the user installed; it never installs, downloads, or executes anything that could download. `probe` reads only: config (design_detector off → DISABLED), IMPECCABLE_BIN (absolute, realpath outside the repo and cwd), a PATH walk (absolute entries outside the repo; a #! shim counts as launcher-present, never READY), the ~/.impeccable/bin/<newest semver>/ cache, and the engine installed beside a skill launcher (scripts/bin/<os>-<arch>/impeccable, the layout a real install produced). It reports IMPECCABLE_SKILL, host-aware IMPECCABLE_HOOK (+ HOOK_OTHER), the ignore lists from .impeccable/config*.json, IMPECCABLE_ENGINE_UNTESTED for versions outside the fixture set, and a hint only when a launcher exists without its engine. `scan` re-probes, refuses URLs and anything outside the repo root or the design-report allow-list (realpath, so symlinks cannot escape), derives `--changed <base>` targets NUL-safely through git and lib/frontend-scope.ts, batches 100 absolute paths per engine call with stdin ignored, a SIGKILL timeout, a 50 MB stdout cap, and sanitized length-capped fields, then prints one normalized JSON document (--format gstack) or the engine's bytes (--format raw); DETECT_TOP (fenced as untrusted content), DETECT_SUMMARY, and DETECT_EXIT go to stderr; exit code passes through with 1 over 2 over 0; exit 3 is a gstack bug. `rules` prints the mapped set. Every run appends a content-free line to the local analytics file. lib/design-detect-contract.ts owns every sentinel string, the limits, and the normalized-finding shape (pure module); test/design-detect-contract.test.ts asserts every sentinel-shaped token the agent can read exists there. lib/frontend-scope.ts mirrors gstack-diff-scope's frontend arm, pinned by a parity test that runs the bash script. bin/gstack-config gains design_detector (auto | off, default auto, invalid values rejected with the file unchanged). test/fixtures/fake-impeccable.ts is the env-driven engine stand-in; test/gstack-design-detect.test.ts covers READY/NOT_CACHED/ NOT_AVAILABLE/DISABLED, env trust (.env never loaded, in-repo IMPECCABLE_BIN ignored), newest-semver cache, hook and ignore detection, refusals, exit passthrough, raw byte-identity, normalization, the display cap, timeout, parse errors, diagnostics, --changed, and analytics. The egress scanner test records the wrapper as a documented non-sink. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
71505f8374
commit
3867dae355
+16
-2
@@ -122,6 +122,13 @@ CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on ne
|
||||
# # /document-release skip the outside-voice step entirely.
|
||||
# # An invalid value is REJECTED (existing value preserved) so
|
||||
# # a typo cannot silently turn paid Codex calls on or off.
|
||||
# design_detector: auto # Deterministic design pre-pass through a user-installed
|
||||
# # impeccable engine (/design-review, /review, /ship,
|
||||
# # /design-html). auto = use the engine when the probe
|
||||
# # finds one (gstack never installs or downloads it);
|
||||
# # off = no probe, no scan, no hint, no /impeccable
|
||||
# # handoff lines. An invalid value is REJECTED (existing
|
||||
# # value preserved) so a typo cannot silently disable it.
|
||||
# gstack_contributor: false # true = file field reports when gstack misbehaves
|
||||
# skip_eng_review: false # true = skip eng review gate in /ship (not recommended)
|
||||
#
|
||||
@@ -149,6 +156,7 @@ lookup_default() {
|
||||
checkpoint_push) echo "false" ;;
|
||||
explain_level) echo "default" ;;
|
||||
codex_reviews) echo "enabled" ;;
|
||||
design_detector) echo "auto" ;; # auto | off — impeccable engine pre-pass in the design skills
|
||||
gstack_contributor) echo "false" ;;
|
||||
skip_eng_review) echo "false" ;;
|
||||
workspace_root) echo "$HOME/conductor/workspaces" ;;
|
||||
@@ -416,6 +424,12 @@ case "${1:-}" in
|
||||
echo "Error: codex_reviews '$VALUE' not recognized. Valid values: enabled, disabled. Existing value left unchanged." >&2
|
||||
exit 1
|
||||
fi
|
||||
# design_detector gates a third-party binary the user installed. Reject a typo
|
||||
# rather than coerce it: "of" must not silently re-enable or disable the scan.
|
||||
if [ "$KEY" = "design_detector" ] && [ "$VALUE" != "auto" ] && [ "$VALUE" != "off" ]; then
|
||||
echo "Error: design_detector '$VALUE' not recognized. Valid values: auto, off. Existing value left unchanged." >&2
|
||||
exit 1
|
||||
fi
|
||||
# cross_project_learnings: empty get is the first-run prompt sentinel.
|
||||
# Skills enable only on the literal "true". A typo must not persist — that
|
||||
# keeps the feature off and suppresses the prompt. Reject, like
|
||||
@@ -455,7 +469,7 @@ case "${1:-}" in
|
||||
skill_prefix checkpoint_mode checkpoint_push explain_level \
|
||||
codex_reviews gstack_contributor skip_eng_review workspace_root \
|
||||
artifacts_sync_mode artifacts_sync_mode_prompted plan_tune_hooks \
|
||||
timeline_stop_hook; do
|
||||
timeline_stop_hook design_detector; do
|
||||
VALUE=$(read_config_value "$KEY" || true)
|
||||
SOURCE="default"
|
||||
if [ -n "$VALUE" ]; then
|
||||
@@ -472,7 +486,7 @@ case "${1:-}" in
|
||||
skill_prefix checkpoint_mode checkpoint_push explain_level \
|
||||
codex_reviews gstack_contributor skip_eng_review workspace_root \
|
||||
artifacts_sync_mode artifacts_sync_mode_prompted plan_tune_hooks \
|
||||
timeline_stop_hook; do
|
||||
timeline_stop_hook design_detector; do
|
||||
printf ' %-24s %s\n' "$KEY:" "$(lookup_default "$KEY")"
|
||||
done
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user