Skip to main content

flag-parser

Parses workflow flags (--quality-locked, --autonomous, --subagents) from $ARGUMENTS at the start of /build and /architect commands. Uses a deterministic python3 runtime with a prose-rule fallback if python3 is unavailable. Returns a strict JSON contract that the agent trusts unconditionally.

설치로 이동

소스 정보

저장소
xoai/sage
최근 소스 활동
2026년 8월 9일 07:20
감지된 SKILL.md 언어
영어
스타
26
포크
7

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
flag-parser
description
Parses workflow flags (--quality-locked, --autonomous, --subagents) from $ARGUMENTS at the start of /build and /architect commands. Uses a deterministic python3 runtime with a prose-rule fallback if python3 is unavailable. Returns a strict JSON contract that the agent trusts unconditionally.
version
1.1.0
modes
["build","architect"]
type
process
# Flag Parser Workflow flags are passed inline in slash command arguments. Both `/build` and `/architect` accept the same flags, parsed identically. **Parsing must be deterministic.** Prose-only parsing by the agent is unreliable — the runtime layers below produce the same JSON output and the agent trusts that JSON unconditionally. ## Supported Flags | Flag | Effect | Default | |------|--------|---------| | `--quality-locked` | Loop review/revise until findings are clean or cap (10) hit | off (overridable by config) | | `--no-quality-locked` | Force off, overriding a config default | — | | `--autonomous` | Agent makes elicitation decisions from memory/codebase/principles | off (overridable by config) | | `--no-autonomous` | Force off, overriding a config default | — | | `--subagents` | Fresh implementer + reviewer subagent per plan task (ADR-10) | off (overridable by config) | | `--no-subagents` | Force off, overriding a config default | — | | `--parallel[=N]` | Dependency-aware parallel lanes on top of `--subagents` (A7); the one value-taking flag — N is the lane cap, default 2, hard cap 4 (over-asking clamps loudly into `parallel_note`) | off (overridable by config) | | `--no-parallel` | Force off, overriding a config default | — | **`--subagents` is different from the other two, and the difference matters.** The others are policies: ask for them and you get them. This one is a *capability* — it requires the platform contract's `subagent-dispatch`. Where that is absent, the request is REFUSED, not silently downgraded: the workflow announces it, the degradation hook writes a `decisions.md` line, and the manifest records `execution_mode: inline (subagents-unavailable)`. Call `resolve_execution_mode()` in `sage_flags.py` rather than reading the flag directly — a bare flag read is how a "fresh reviewer per task" quietly becomes the same context reviewing itself. ## Precedence (highest wins) For each mode (quality_locked, autonomous, subagents — the ladder is the same for all three; subagents' extra step, platform refusal, happens AFTER parsing, R97): | Priority | Source | Effect | Source label | |----------|--------|--------|--------------| | 1 (highest) | `--no-<flag>` | Force off | `"flag"` | | 2 | `--<flag>` | Force on | `"flag"` | | 3 | `<flag>: true` in `.sage/config.yaml` | Default on | `"config"` | | 4 (lowest) | nothing | Off (current behavior) | `null` | **Flag vs config when they agree:** the source label is `"flag"` (explicit intent always labels, even when the value matches config). Functional outcome is the same (mode on). **Conflict:** passing `--<flag>` AND `--no-<flag>` in the same invocation is a user error. The parser returns an error JSON and exits non-zero. ## Config File Defaults Read from `.sage/config.yaml`. Strict-match contract: only lines matching exactly `<key>: true` (with one space after the colon, lowercase `true`, no trailing characters) are honored. The strict form ensures Python and the prose rules agree byte-for-byte. Rejected variants (treated as no default): - `quality_locked: True` (titlecase) - `quality_locked: "true"` (quoted) - `quality_locked: yes` (YAML alias) - `quality_locked:true` (no space) - `quality_locked: true` (extra space) - `quality_locked: true # comment` (trailing content) - Any nested/indented key (only top-level keys are read) `quality_locked: false` is equivalent to no default — value is off. Use the `--quality-locked` flag to override. ## JSON Contract Both parsing layers emit the same JSON shape to stdout: ```json { "quality_locked": true | false, "autonomous": true | false, "subagents": true | false, "parallel": true | false, "goal": "<remainder after flags, trimmed>", "error": null | "<error message>", "quality_locked_source": "flag" | "config" | null, "autonomous_source": "flag" | "config" | null, "subagents_source": "flag" | "config" | null, "parallel_source": "flag" | "config" | null, "parallel_lanes": 0 | 1-4, "parallel_note": null | "<clamp note>" } ``` Source value is `"flag"` whenever a flag (positive `--X` or negative `--no-X`) influenced the result. `"config"` only when no flag was passed AND config provides the default-on. `null` when the value is the implicit default-off. Exit code semantics: - `0` — clean parse (`error: null`) - `1` — unknown flag, conflicting flags, or malformed input (`error` is populated; JSON still printed) ## Parsing Order (Try Each Layer) The agent tries each layer in order. As soon as one returns valid JSON, use it and skip the rest. ### Layer 1 — Python (primary, preferred) ```bash python3 sage/runtime/tools/sage_flags.py parse "$ARGUMENTS" --config-path .sage/config.yaml ``` The `--config-path` is optional — when provided, the parser reads `quality_locked: true` / `autonomous: true` lines as defaults. When omitted (or the file is missing/malformed), no defaults apply. Outputs JSON to stdout. Exit 0 on clean parse, 1 on unknown flag or conflict. ### Layer 2 — Prose-rule fallback (last resort) Use ONLY when Python is unavailable (rare — Sage requires python3, so this is a locked-down or broken environment). The agent reads the parsing rules below and produces JSON manually. **Announce when falling back:** ``` Sage: Deterministic parser unavailable (python3 not found). Using prose-rule fallback for flag parsing. ``` This is the only case where prose parsing is acceptable. ## Parsing Rules (used by both layers) 1. **Flags must appear before the goal description.** Flags at the end are not parsed — they're treated as part of the goal. 2. **Flag order doesn't matter.** `--autonomous --quality-locked` and `--quality-locked --autonomous` are equivalent. 3. **Unknown flags are an error.** If $ARGUMENTS starts with `--` and the flag name isn't recognized, return JSON with `error` populated. 4. **No values, just booleans.** Neither flag takes an argument. `--quality-locked=true` is not supported. 5. **Goal is everything after the flags.** Surrounding whitespace trimmed; internal whitespace preserved. ## Examples ``` INPUT: "Ship dark mode" OUTPUT: {"quality_locked": false, "autonomous": false, "goal": "Ship dark mode", "error": null} INPUT: "--quality-locked Ship dark mode" OUTPUT: {"quality_locked": true, "autonomous": false, "goal": "Ship dark mode", "error": null} INPUT: "--autonomous --quality-locked Ship dark mode" OUTPUT: {"quality_locked": true, "autonomous": true, "goal": "Ship dark mode", "error": null} INPUT: "--quality-locked" OUTPUT: {"quality_locked": true, "autonomous": false, "goal": "", "error": null} INPUT: "Ship --quality-locked dark mode" # flag not at start OUTPUT: {"quality_locked": false, "autonomous": false, "goal": "Ship --quality-locked dark mode", "error": null} INPUT: "--foo bar" OUTPUT: {"quality_locked": false, "autonomous": false, "goal": "", "error": "Unknown flag '--foo'. Supported flags: --quality-locked, --autonomous."} EXIT: 1 ``` ## After Parsing ### On clean parse (error: null) 1. Use `quality_locked` and `autonomous` booleans for the rest of the workflow. 2. Use `goal` as the user's task description (may be empty — workflow will auto-pickup from `.sage/work/`). 3. Announce active modes (if any) before starting work: ``` Sage → build workflow. Modes: --quality-locked, --autonomous Goal: Ship dark mode for the dashboard ``` If both flags are false, omit the Modes line entirely. ### On error (error populated) Surface the error verbatim to the user and stop the workflow: ``` Sage: {error message} ``` Do NOT guess what the user meant. Wait for them to retry with the correct flag name. ## Manifest Persistence After successful parsing, before starting Step 1, the workflow writes flag state to manifest.md frontmatter: ```yaml flags: quality_locked: true autonomous: true ``` On `/continue`, the workflow reads these fields and restores both modes for the duration of the session. ## Failure Modes | Situation | Behavior | |---|---| | Python missing | Fall through to the prose-rule layer (announce degradation) | | Unknown flag | Surface error message, stop workflow | | Empty $ARGUMENTS | Both modes off, empty goal — workflow may scan `.sage/work/` for active initiative | | `/continue` overrides | New invocation's flags override manifest; note to user | ## Quality Criteria - Parser is deterministic — same input always produces same output - Both layers produce IDENTICAL JSON for the same input (verified by parity tests) - Error messages name the unknown flag and list supported flags - Goal preserves user-supplied whitespace and casing - Flag state is announced and persisted before any artifact work begins - Prose-fallback announcement is mandatory so the user knows reliability is degraded
GitHub에서 보기