← the whole session plugin/skills/declare-scope/SKILL.md
Decompose a task into testable UX intent statements and post to compaction. Use at the start of every non-trivial task.
Declare Scope
Before your output, print ## SCOPE_DECLARATION on its own line. This enables automated extraction to the compaction admin UI.
After your scope output is complete, print ## END_SCOPE_DECLARATION on its own line. This closes the extraction block.
One function. Reason about the human's intent, decompose it, post it, print it.
When to invoke
- At the start of every non-trivial task (governer score >= 20)
- When the human changes direction mid-session
- When you realize your understanding was wrong
What you do
Step 1: Reason
REQUIRED: Consume /how-to-articulate-intent before writing any statements. That skill defines the format, wrong/right examples, and rules.
Decompose the human's request into atomic statements using the two formats:
- System intent: When {every condition as experienced} then {system, named by function} should {behavior as effect on person}
- UX intent: When {every condition as person's state} then {the person} should {what happens for them, code-precise in human terms}
Rules for each statement:
- Atomic — one testable thing
- Precise — as specific as code
- Human-readable — any stakeholder can understand it
- Never use code variable names when a UX-equivalent exists
- Wrong: "when
accountTier === 1andbillingCustomerIdexists" - Right: "when the user is on the free tier and has a payment method on file"
- Wrong: "when
Auto-mining triggers — when the human says any of these, an intent exists to be captured:
| Pattern | Example |
|---|---|
| "users should never..." | "users should never see a blank screen after paying" |
| "users should always..." | "users should always know their trial status" |
| "when X happens, they should see Y" | "when they upgrade, they should see a confirmation" |
| "never show X when Y" | "never show upgrade CTA to a paying user" |
| "this is broken because [UX description]" | "this is broken because free users see paid features" |
Step 2: Post — use declareScope() function
Run the function below. It resolves the session ID, validates the inputs, and writes the declaration to a local record so it survives past this chat window — no server or API key required. If you've wired your own Intent DB or compaction API (see /intent-db, if you've set one up), it's an optional add-on you layer on top of this, not a replacement for it — the local write always happens first and always succeeds on its own.
# Call this function — do NOT manually construct curl calls
declareScope() {
# --- Resolve session ID the harness's own way (works with no other setup) ---
local SESSION_ID
SESSION_ID=$(alignment-harness session-id 2>/dev/null)
if [ -z "$SESSION_ID" ] || [ "$SESSION_ID" = "unknown-session" ]; then
echo "⚠️ DECLARE-SCOPE: no session id resolved (alignment-harness not on PATH, or hooks not running) — using a generated id for this record"
SESSION_ID="session-$(date +%s)"
fi
local SUMMARY="$1" # one-line summary of what the human asked for
local DECOMPOSED="$2" # JSON array: ["When X → Y", "When A → B"]
local BOUNDARY="$3" # what is NOT in scope
local VERIFICATION="$4" # runnable command that proves it works
local CERTAINTY="${5:-85}" # 0-100
# --- Validate inputs ---
if [ -z "$SUMMARY" ] || [ -z "$DECOMPOSED" ]; then
echo "❌ DECLARE-SCOPE FAILED: Missing required arguments"
echo " → Usage: declareScope 'summary' '[\"When X → Y\"]' 'boundary' 'verification' 85"
echo " → You must provide at least summary and decomposed statements"
return 1
fi
local INTENT_COUNT=$(echo "$DECOMPOSED" | jq 'length' 2>/dev/null || echo 0)
# --- Write the local record (this is the primary, always-on persistence) ---
local RECORDS_DIR
RECORDS_DIR=$(alignment-harness records scope-declarations 2>/dev/null)
if [ -z "$RECORDS_DIR" ]; then
echo "❌ DECLARE-SCOPE: could not resolve the records folder — is alignment-harness on PATH?"
echo " → Falling back to printing the declaration only; nothing was saved."
return 1
fi
mkdir -p "$RECORDS_DIR"
local OUT_FILE="$RECORDS_DIR/${SESSION_ID}-$(date +%s).json"
jq -n \
--arg sessionId "$SESSION_ID" \
--arg summary "$SUMMARY" \
--argjson decomposed "$DECOMPOSED" \
--arg boundary "${BOUNDARY:-not specified}" \
--arg verification "${VERIFICATION:-not specified}" \
--argjson certainty "$CERTAINTY" \
--arg postedAt "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{
sessionId: $sessionId,
summary: $summary,
decomposed: $decomposed,
boundary: $boundary,
verification: $verification,
certainty: $certainty,
postedAt: $postedAt
}' > "$OUT_FILE"
local WRITE_OK=1
if [ ! -s "$OUT_FILE" ]; then
WRITE_OK=0
fi
# --- Optional: if the person has their own Intent DB / compaction API configured, sync to it too ---
# This is additive and never blocks the local write above. If /intent-db (or your own
# equivalent) isn't set up, skip this silently — the local record is already the source of truth.
# --- Report back to the invoking agent ---
echo ""
echo "━━━ DECLARE-SCOPE RESULT ━━━"
echo "Session: $SESSION_ID"
echo "Statements in this scope: $INTENT_COUNT"
if [ "$WRITE_OK" = "1" ]; then
echo "Saved: $OUT_FILE"
else
echo "❌ Local write FAILED — $OUT_FILE is empty or missing. Check that $RECORDS_DIR is writable."
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ "$WRITE_OK" != "1" ]; then
return 1
fi
return 0
}
How to use:
declareScope \
"Unify intent lifecycle and scope declaration into one skill" \
'["When an agent starts a task → it decomposes intent and writes a local scope record in one call", "When the scope is saved → it prints to chat so the human can correct in real-time", "When saving fails → the error and next step are reported back to the agent"]' \
"Not changing the Intent DB schema or the plugin's own record format" \
"cat the saved JSON file and confirm the decomposed/boundary/verification/certainty fields are populated" \
90
Step 3: Print to chat
After calling declareScope(), print the decomposition to the human. The function reports success/failure, but YOU print the human-readable scope:
📋 Scope: {one-line summary of what the human asked for}
When {constraints} → {testable UX outcome}
When {constraints} → {testable UX outcome}
When {constraints} → {testable UX outcome}
Boundary: {what is NOT in scope}
Verification: {runnable command that proves it works}
Certainty: {0-100} — {why this number}
Do NOT block waiting for approval — /governer decides whether to act or propose.
Certainty scale:
- 95-100: Human was explicit, requirements unambiguous
- 85-94: Clear intent, some details need assumptions — state them
- 70-84: Direction clear, specifics fuzzy — reflect, then proceed with best prediction
- Below 70: Predict the most likely intent, propose it as default assumption, proceed. NEVER stop to ask.
Step 4: Governer
After printing, invoke /governer on the first decomposed task. Governer scores it and decides: act directly or propose for human review.
Error handling
Every failure reports back to you with:
- What failed (Intent DB write, compaction write, session ID resolution)
- Why (the actual error message from the API)
- What to do next (specific fix action)
If declareScope() returns non-zero, read the error output and fix the issue before proceeding. Do NOT ignore errors and claim scope was posted.
Two-Layer ID System
Every intent gets two identifiers. Pick a short prefix for your own project at setup (your project's initials, or a plain running number) — the examples below use PROJ- as a placeholder:
- Machine layer:
PROJ-042(3-4 tokens) — use in code comments (// @intent: PROJ-042), commits (Intents: PROJ-042), agent context - Human layer: Full UX statement — use in test names, UX assignments, changelogs, chat
If you have an Intent DB set up (see /intent-db), it resolves the ID to the full intent record. Without one, the local scope-declaration record (below) and git log --grep are the registry.
Intent Through Phases
| Phase | What happens with intent |
|---|---|
| Discovery | Decompose → post → print (this skill) |
| Planning | Reference the intent ID in the plan, flag gaps |
| Implementation | Tag code: // @intent: PROJ-042 at entry points and error paths |
| TDD | Test file header: @intents-covered: PROJ-042, PROJ-043 |
| Commit | Body includes Intents: PROJ-042 |
| Audit | git log --grep="Intents:" --oneline traces intent through commits |
Where the record lives
After posting, the function prints the path it saved to — a JSON file under the folder alignment-harness records scope-declarations prints. Open that file directly, or grep across the folder, to see every scope this project has declared. There's no admin UI required for this to work; if you've built one on top of your own Intent DB setup, point it at that same folder or your synced copy.