create-agdf 0.11.2 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -169,6 +169,15 @@ If a status is not explicit, do not assume it is satisfied.
169
169
  11. When `.agdf/control/` is missing or incomplete, make the next allowed artefact action explicit. For a fresh request, that means draft the minimal UR in the response, then request `Approval: UR`. Do not write a full control scaffold unless durable control state was explicitly requested or is already the repository's live AGDF working state.
170
170
  12. If branch, workspace and durable artefacts disagree, do not choose a scope silently; report the ambiguity and ask for the smallest clarifying gate action.
171
171
 
172
+ ### Scope Classification Output
173
+ When this skill classifies a fresh scope as ungated (Quick Task or Trivial Change Boundary), consume
174
+ `scope_classification.markdown` verbatim from `renderScopeClassificationCard` in
175
+ `../contracts/interaction.md` § Scope Classification Card. The card is a compact, localized,
176
+ non-authorizing projection: mode, boundary, UR-trigger evaluation, one allowed line, one forbidden
177
+ line, escalation triggers and the challenge path. Do not maintain or render a skill-local
178
+ classification card template. If the renderer returns `null`, fail closed to the existing ceremony
179
+ and do not model-reconstruct Markdown.
180
+
172
181
  ## Output
173
182
  Keep the result short and operational. For a status-only response, consume the Runtime Contract's
174
183
  code-owned `status_presentation.markdown` verbatim. It is the compact localized operational Run
@@ -39,6 +39,25 @@
39
39
  "breadcrumbOpen": "\u25cb",
40
40
  "breadcrumbSeparator": " \u00b7 "
41
41
  },
42
+ "scopeClassification": {
43
+ "title": "AGDF scope classification",
44
+ "field": "Field",
45
+ "value": "Value",
46
+ "classification": "Classification",
47
+ "mode": {
48
+ "quick_task": "Quick Task",
49
+ "verified_change": "Verified Change"
50
+ },
51
+ "boundary": {
52
+ "inside": "Trivial change boundary satisfied",
53
+ "outside": "Outside trivial change boundary"
54
+ },
55
+ "grounds": "UR trigger evaluation",
56
+ "allowed": "Currently allowed",
57
+ "forbidden": "Remains forbidden",
58
+ "escalation": "Escalation triggers",
59
+ "challenge": "Challenge path"
60
+ },
42
61
  "internalStateLabels": {
43
62
  "verifiedChange": "Compact change under review",
44
63
  "verifiedChangeEscalated": "Escalated to structured delivery",
@@ -246,6 +265,25 @@
246
265
  "breadcrumbOpen": "\u25cb",
247
266
  "breadcrumbSeparator": " \u00b7 "
248
267
  },
268
+ "scopeClassification": {
269
+ "title": "AGDF-Scope-Klassifizierung",
270
+ "field": "Feld",
271
+ "value": "Wert",
272
+ "classification": "Klassifizierung",
273
+ "mode": {
274
+ "quick_task": "Quick Task",
275
+ "verified_change": "Verified Change"
276
+ },
277
+ "boundary": {
278
+ "inside": "Trivial-Change-Boundary erfüllt",
279
+ "outside": "Außerhalb der Trivial-Change-Boundary"
280
+ },
281
+ "grounds": "UR-Trigger-Evaluation",
282
+ "allowed": "Aktuell erlaubt",
283
+ "forbidden": "Bleibt verboten",
284
+ "escalation": "Eskalationsauslöser",
285
+ "challenge": "Widerspruchspfad"
286
+ },
249
287
  "internalStateLabels": {
250
288
  "verifiedChange": "Kompakte Änderung wird geprüft",
251
289
  "verifiedChangeEscalated": "Eskaliert zu structured delivery",
@@ -338,6 +338,25 @@ repeat the sentence later in the same request. Existing-run status inspection re
338
338
  uses the existing status projection; this branch must not create a second status-card or narration
339
339
  owner.
340
340
 
341
+ ### Scope Classification Card
342
+
343
+ When `agdf-gate-check` classifies a fresh scope as ungated (Quick Task or Trivial Change Boundary),
344
+ the agent consumes the canonical `scope_classification.markdown` verbatim from
345
+ `renderScopeClassificationCard` in `create-agdf/lib/interaction-presentation.js`. The card is a
346
+ compact, localized, non-authorizing projection of the classification: mode, boundary result,
347
+ UR-trigger evaluation, one currently-allowed line, one remains-forbidden line, escalation triggers
348
+ and the challenge path. It carries `authorizes: false` and never renders approval controls.
349
+
350
+ The card renders exactly once per fresh-scope ungated classification, before work proceeds. It must
351
+ not appear for gated scopes, internal steps of a selected run, or as a substitute for the two-card
352
+ approval envelope. Read-only requests keep the single read-only orientation sentence above; the
353
+ scope classification card and the read-only orientation are mutually exclusive for the same request.
354
+
355
+ If the classification input is missing, unknown, contradictory or the locale section is incomplete,
356
+ the renderer returns `null` and the agent fails closed to the existing ceremony — never
357
+ model-reconstructed Markdown. The card introduces no gate, no approval value, no persistence and no
358
+ second presentation owner. `agdf-gate-check` must not maintain a skill-local card template.
359
+
341
360
  Exact textual approvals remain canonical and fully supported on every surface. If native capability availability or safety is unknown, use the textual fallback. Host permission, plan approval, native question presentation, timeout/default behavior, hook output and agent messages never carry AGDF gate authority by themselves.
342
361
 
343
362
  ### Interaction Locale Contract
@@ -39,6 +39,25 @@
39
39
  "breadcrumbOpen": "\u25cb",
40
40
  "breadcrumbSeparator": " \u00b7 "
41
41
  },
42
+ "scopeClassification": {
43
+ "title": "AGDF scope classification",
44
+ "field": "Field",
45
+ "value": "Value",
46
+ "classification": "Classification",
47
+ "mode": {
48
+ "quick_task": "Quick Task",
49
+ "verified_change": "Verified Change"
50
+ },
51
+ "boundary": {
52
+ "inside": "Trivial change boundary satisfied",
53
+ "outside": "Outside trivial change boundary"
54
+ },
55
+ "grounds": "UR trigger evaluation",
56
+ "allowed": "Currently allowed",
57
+ "forbidden": "Remains forbidden",
58
+ "escalation": "Escalation triggers",
59
+ "challenge": "Challenge path"
60
+ },
42
61
  "internalStateLabels": {
43
62
  "verifiedChange": "Compact change under review",
44
63
  "verifiedChangeEscalated": "Escalated to structured delivery",
@@ -246,6 +265,25 @@
246
265
  "breadcrumbOpen": "\u25cb",
247
266
  "breadcrumbSeparator": " \u00b7 "
248
267
  },
268
+ "scopeClassification": {
269
+ "title": "AGDF-Scope-Klassifizierung",
270
+ "field": "Feld",
271
+ "value": "Wert",
272
+ "classification": "Klassifizierung",
273
+ "mode": {
274
+ "quick_task": "Quick Task",
275
+ "verified_change": "Verified Change"
276
+ },
277
+ "boundary": {
278
+ "inside": "Trivial-Change-Boundary erfüllt",
279
+ "outside": "Außerhalb der Trivial-Change-Boundary"
280
+ },
281
+ "grounds": "UR-Trigger-Evaluation",
282
+ "allowed": "Aktuell erlaubt",
283
+ "forbidden": "Bleibt verboten",
284
+ "escalation": "Eskalationsauslöser",
285
+ "challenge": "Widerspruchspfad"
286
+ },
249
287
  "internalStateLabels": {
250
288
  "verifiedChange": "Kompakte Änderung wird geprüft",
251
289
  "verifiedChangeEscalated": "Eskaliert zu structured delivery",
@@ -338,6 +338,25 @@ repeat the sentence later in the same request. Existing-run status inspection re
338
338
  uses the existing status projection; this branch must not create a second status-card or narration
339
339
  owner.
340
340
 
341
+ ### Scope Classification Card
342
+
343
+ When `agdf-gate-check` classifies a fresh scope as ungated (Quick Task or Trivial Change Boundary),
344
+ the agent consumes the canonical `scope_classification.markdown` verbatim from
345
+ `renderScopeClassificationCard` in `create-agdf/lib/interaction-presentation.js`. The card is a
346
+ compact, localized, non-authorizing projection of the classification: mode, boundary result,
347
+ UR-trigger evaluation, one currently-allowed line, one remains-forbidden line, escalation triggers
348
+ and the challenge path. It carries `authorizes: false` and never renders approval controls.
349
+
350
+ The card renders exactly once per fresh-scope ungated classification, before work proceeds. It must
351
+ not appear for gated scopes, internal steps of a selected run, or as a substitute for the two-card
352
+ approval envelope. Read-only requests keep the single read-only orientation sentence above; the
353
+ scope classification card and the read-only orientation are mutually exclusive for the same request.
354
+
355
+ If the classification input is missing, unknown, contradictory or the locale section is incomplete,
356
+ the renderer returns `null` and the agent fails closed to the existing ceremony — never
357
+ model-reconstructed Markdown. The card introduces no gate, no approval value, no persistence and no
358
+ second presentation owner. `agdf-gate-check` must not maintain a skill-local card template.
359
+
341
360
  Exact textual approvals remain canonical and fully supported on every surface. If native capability availability or safety is unknown, use the textual fallback. Host permission, plan approval, native question presentation, timeout/default behavior, hook output and agent messages never carry AGDF gate authority by themselves.
342
361
 
343
362
  ### Interaction Locale Contract
@@ -169,6 +169,15 @@ If a status is not explicit, do not assume it is satisfied.
169
169
  11. When `.agdf/control/` is missing or incomplete, make the next allowed artefact action explicit. For a fresh request, that means draft the minimal UR in the response, then request `Approval: UR`. Do not write a full control scaffold unless durable control state was explicitly requested or is already the repository's live AGDF working state.
170
170
  12. If branch, workspace and durable artefacts disagree, do not choose a scope silently; report the ambiguity and ask for the smallest clarifying gate action.
171
171
 
172
+ ### Scope Classification Output
173
+ When this skill classifies a fresh scope as ungated (Quick Task or Trivial Change Boundary), consume
174
+ `scope_classification.markdown` verbatim from `renderScopeClassificationCard` in
175
+ `../../contracts/interaction.md` § Scope Classification Card. The card is a compact, localized,
176
+ non-authorizing projection: mode, boundary, UR-trigger evaluation, one allowed line, one forbidden
177
+ line, escalation triggers and the challenge path. Do not maintain or render a skill-local
178
+ classification card template. If the renderer returns `null`, fail closed to the existing ceremony
179
+ and do not model-reconstruct Markdown.
180
+
172
181
  ## Output
173
182
  Keep the result short and operational. For a status-only response, consume the Runtime Contract's
174
183
  code-owned `status_presentation.markdown` verbatim. It is the compact localized operational Run
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdf",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "AI Governance & Delivery Framework (AGDF) brings an operating system for governed AI-assisted delivery to Claude Code, combining workflow skills, control templates and machine-readable repository checks for gate decisions, Brownfield analysis, task-plan review, QA decisions, durable run state and auditable closeout.",
5
5
  "keywords": [
6
6
  "agentic",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdf",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "Operating system for governed AI-assisted delivery.",
5
5
  "author": {
6
6
  "name": "Arndt Gold",
@@ -39,6 +39,25 @@
39
39
  "breadcrumbOpen": "\u25cb",
40
40
  "breadcrumbSeparator": " \u00b7 "
41
41
  },
42
+ "scopeClassification": {
43
+ "title": "AGDF scope classification",
44
+ "field": "Field",
45
+ "value": "Value",
46
+ "classification": "Classification",
47
+ "mode": {
48
+ "quick_task": "Quick Task",
49
+ "verified_change": "Verified Change"
50
+ },
51
+ "boundary": {
52
+ "inside": "Trivial change boundary satisfied",
53
+ "outside": "Outside trivial change boundary"
54
+ },
55
+ "grounds": "UR trigger evaluation",
56
+ "allowed": "Currently allowed",
57
+ "forbidden": "Remains forbidden",
58
+ "escalation": "Escalation triggers",
59
+ "challenge": "Challenge path"
60
+ },
42
61
  "internalStateLabels": {
43
62
  "verifiedChange": "Compact change under review",
44
63
  "verifiedChangeEscalated": "Escalated to structured delivery",
@@ -246,6 +265,25 @@
246
265
  "breadcrumbOpen": "\u25cb",
247
266
  "breadcrumbSeparator": " \u00b7 "
248
267
  },
268
+ "scopeClassification": {
269
+ "title": "AGDF-Scope-Klassifizierung",
270
+ "field": "Feld",
271
+ "value": "Wert",
272
+ "classification": "Klassifizierung",
273
+ "mode": {
274
+ "quick_task": "Quick Task",
275
+ "verified_change": "Verified Change"
276
+ },
277
+ "boundary": {
278
+ "inside": "Trivial-Change-Boundary erfüllt",
279
+ "outside": "Außerhalb der Trivial-Change-Boundary"
280
+ },
281
+ "grounds": "UR-Trigger-Evaluation",
282
+ "allowed": "Aktuell erlaubt",
283
+ "forbidden": "Bleibt verboten",
284
+ "escalation": "Eskalationsauslöser",
285
+ "challenge": "Widerspruchspfad"
286
+ },
249
287
  "internalStateLabels": {
250
288
  "verifiedChange": "Kompakte Änderung wird geprüft",
251
289
  "verifiedChangeEscalated": "Eskaliert zu structured delivery",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "agdf",
4
- "version": "0.11.2",
4
+ "version": "0.11.3",
5
5
  "displayName": "AI Governance & Delivery Framework",
6
6
  "developerName": "Arndt Gold",
7
7
  "description": "Operating system for governed AI-assisted delivery.",
@@ -338,6 +338,25 @@ repeat the sentence later in the same request. Existing-run status inspection re
338
338
  uses the existing status projection; this branch must not create a second status-card or narration
339
339
  owner.
340
340
 
341
+ ### Scope Classification Card
342
+
343
+ When `gate-check` classifies a fresh scope as ungated (Quick Task or Trivial Change Boundary),
344
+ the agent consumes the canonical `scope_classification.markdown` verbatim from
345
+ `renderScopeClassificationCard` in `create-agdf/lib/interaction-presentation.js`. The card is a
346
+ compact, localized, non-authorizing projection of the classification: mode, boundary result,
347
+ UR-trigger evaluation, one currently-allowed line, one remains-forbidden line, escalation triggers
348
+ and the challenge path. It carries `authorizes: false` and never renders approval controls.
349
+
350
+ The card renders exactly once per fresh-scope ungated classification, before work proceeds. It must
351
+ not appear for gated scopes, internal steps of a selected run, or as a substitute for the two-card
352
+ approval envelope. Read-only requests keep the single read-only orientation sentence above; the
353
+ scope classification card and the read-only orientation are mutually exclusive for the same request.
354
+
355
+ If the classification input is missing, unknown, contradictory or the locale section is incomplete,
356
+ the renderer returns `null` and the agent fails closed to the existing ceremony — never
357
+ model-reconstructed Markdown. The card introduces no gate, no approval value, no persistence and no
358
+ second presentation owner. `gate-check` must not maintain a skill-local card template.
359
+
341
360
  Exact textual approvals remain canonical and fully supported on every surface. If native capability availability or safety is unknown, use the textual fallback. Host permission, plan approval, native question presentation, timeout/default behavior, hook output and agent messages never carry AGDF gate authority by themselves.
342
361
 
343
362
  ### Interaction Locale Contract
@@ -39,6 +39,25 @@
39
39
  "breadcrumbOpen": "\u25cb",
40
40
  "breadcrumbSeparator": " \u00b7 "
41
41
  },
42
+ "scopeClassification": {
43
+ "title": "AGDF scope classification",
44
+ "field": "Field",
45
+ "value": "Value",
46
+ "classification": "Classification",
47
+ "mode": {
48
+ "quick_task": "Quick Task",
49
+ "verified_change": "Verified Change"
50
+ },
51
+ "boundary": {
52
+ "inside": "Trivial change boundary satisfied",
53
+ "outside": "Outside trivial change boundary"
54
+ },
55
+ "grounds": "UR trigger evaluation",
56
+ "allowed": "Currently allowed",
57
+ "forbidden": "Remains forbidden",
58
+ "escalation": "Escalation triggers",
59
+ "challenge": "Challenge path"
60
+ },
42
61
  "internalStateLabels": {
43
62
  "verifiedChange": "Compact change under review",
44
63
  "verifiedChangeEscalated": "Escalated to structured delivery",
@@ -246,6 +265,25 @@
246
265
  "breadcrumbOpen": "\u25cb",
247
266
  "breadcrumbSeparator": " \u00b7 "
248
267
  },
268
+ "scopeClassification": {
269
+ "title": "AGDF-Scope-Klassifizierung",
270
+ "field": "Feld",
271
+ "value": "Wert",
272
+ "classification": "Klassifizierung",
273
+ "mode": {
274
+ "quick_task": "Quick Task",
275
+ "verified_change": "Verified Change"
276
+ },
277
+ "boundary": {
278
+ "inside": "Trivial-Change-Boundary erfüllt",
279
+ "outside": "Außerhalb der Trivial-Change-Boundary"
280
+ },
281
+ "grounds": "UR-Trigger-Evaluation",
282
+ "allowed": "Aktuell erlaubt",
283
+ "forbidden": "Bleibt verboten",
284
+ "escalation": "Eskalationsauslöser",
285
+ "challenge": "Widerspruchspfad"
286
+ },
249
287
  "internalStateLabels": {
250
288
  "verifiedChange": "Kompakte Änderung wird geprüft",
251
289
  "verifiedChangeEscalated": "Eskaliert zu structured delivery",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "agdf",
4
- "version": "0.11.2",
4
+ "version": "0.11.3",
5
5
  "displayName": "AI Governance & Delivery Framework",
6
6
  "developerName": "Arndt Gold",
7
7
  "description": "Operating system for governed AI-assisted delivery.",
@@ -349,6 +349,69 @@ export function renderOperationalStatusCard(statusCard, {
349
349
  });
350
350
  }
351
351
 
352
+ export function renderScopeClassificationCard(classification, {
353
+ registry,
354
+ requestedLocale,
355
+ } = {}) {
356
+ if (!plainObject(classification)) return null;
357
+ const outcome = String(classification.outcome ?? "").trim();
358
+ const mode = String(classification.mode ?? "").trim();
359
+ const trivialBoundary = String(classification.trivial_boundary ?? "").trim();
360
+ const urTriggerEvaluation = String(classification.ur_trigger_evaluation ?? "").trim();
361
+ const allowedSummary = String(classification.allowed_summary ?? "").trim();
362
+ const forbiddenSummary = String(classification.forbidden_summary ?? "").trim();
363
+ const escalationTriggers = Array.isArray(classification.escalation_triggers)
364
+ ? classification.escalation_triggers.map((item) => String(item ?? "").trim()).filter(Boolean)
365
+ : [];
366
+ const challengePath = String(classification.challenge_path ?? "").trim();
367
+
368
+ if (outcome !== "ungated") return null;
369
+ if (!["quick_task", "verified_change"].includes(mode)) return null;
370
+ if (!["inside", "outside"].includes(trivialBoundary)) return null;
371
+ if (!urTriggerEvaluation || !allowedSummary || !forbiddenSummary || !challengePath) return null;
372
+ if (escalationTriggers.length === 0) return null;
373
+
374
+ let locale;
375
+ try {
376
+ locale = resolvePresentationLocale(registry, requestedLocale);
377
+ } catch {
378
+ return null;
379
+ }
380
+ if (!locale) return null;
381
+
382
+ const pack = localePack(registry, locale);
383
+ const labels = pack?.scopeClassification;
384
+ if (!plainObject(labels)) return null;
385
+
386
+ const modeLabel = labels.mode?.[mode] ?? mode;
387
+ const boundaryLabel = labels.boundary?.[trivialBoundary] ?? trivialBoundary;
388
+
389
+ const rows = [
390
+ [labels.classification, `${modeLabel} · ${boundaryLabel}`],
391
+ [labels.grounds, urTriggerEvaluation],
392
+ [labels.allowed, allowedSummary],
393
+ [labels.forbidden, forbiddenSummary],
394
+ [labels.escalation, escalationTriggers.join("; ")],
395
+ [labels.challenge, challengePath],
396
+ ];
397
+
398
+ const markdown = [
399
+ `## ${labels.title ?? "AGDF scope classification"}`,
400
+ "",
401
+ `| ${labels.field ?? "Field"} | ${labels.value ?? "Value"} |`,
402
+ "|---|---|",
403
+ ...rows.map(([label, value]) => `| ${markdownCell(label)} | ${markdownCell(value)} |`),
404
+ ].join("\n");
405
+
406
+ return Object.freeze({
407
+ schema_version: "1",
408
+ semantic_block: "scope_classification_card",
409
+ presentation_language: locale,
410
+ markdown,
411
+ authorizes: false,
412
+ });
413
+ }
414
+
352
415
  export function gateOptions(registry, requestedLocale, gate, { includeCancel = false } = {}) {
353
416
  const pack = localePack(registry, requestedLocale);
354
417
  const options = [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agdf",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "Bootstrap AGDF repository-local plugin files, Copilot/OpenCode instructions, skills, control files and machine-readable checks.",
5
5
  "type": "module",
6
6
  "files": [
@@ -2,7 +2,7 @@
2
2
  "schema_version": "1",
3
3
  "generated": true,
4
4
  "source": "create-agdf/cli",
5
- "version": "0.11.2",
5
+ "version": "0.11.3",
6
6
  "entrypoint": "create-agdf/bin/agdf-validator.js",
7
- "digest": "a4508a485d3954d88c3ba4cd12f007c046f803d181b40bf97ada2f81913224cc"
7
+ "digest": "217946af2b7c5782e9a620c18a0aa3ce351993b4bda8874bbfbf7d8406cc48ff"
8
8
  }
@@ -400,6 +400,28 @@ for (const antiPattern of [
400
400
  if (!runtimeContract.includes("### Repository Activation Diagnosis Boundary")) {
401
401
  failures.push("control-scaffold contract must own the repository activation diagnosis boundary");
402
402
  }
403
+ if (!runtimeContract.includes("### Scope Classification Card")) {
404
+ failures.push("interaction contract must own the scope classification card section");
405
+ }
406
+ if (!gateCheckSkill.includes("scope_classification.markdown` verbatim")) {
407
+ failures.push("gate-check must consume the canonical scope classification projection verbatim");
408
+ }
409
+ if (gateCheckSkill.includes("## Scope Classification Card Template") || gateCheckSkill.includes("| Classification | Mode | Boundary |")) {
410
+ failures.push("gate-check must not maintain a skill-local scope classification card template");
411
+ }
412
+ const interactionPresentationPath = join(pluginRoot, "..", "create-agdf", "lib", "interaction-presentation.js");
413
+ if (sourceMode && isFile(interactionPresentationPath)) {
414
+ const interactionPresentation = read(interactionPresentationPath);
415
+ if (!interactionPresentation.includes("export function renderScopeClassificationCard")) {
416
+ failures.push("interaction-presentation.js must export renderScopeClassificationCard");
417
+ }
418
+ }
419
+ for (const locale of ["en", "de"]) {
420
+ const pack = interactionLocales?.locales?.[locale];
421
+ if (!pack?.scopeClassification?.title || !pack?.scopeClassification?.mode?.quick_task || !pack?.scopeClassification?.challenge) {
422
+ failures.push(`Interaction locale ${locale} missing scopeClassification section keys`);
423
+ }
424
+ }
403
425
  if (!runtimeContract.includes("not an agent-facing diagnosis proof")) {
404
426
  failures.push("control-scaffold contract must classify AGDF_* env vars as non-agent-facing diagnosis");
405
427
  }
@@ -169,6 +169,15 @@ If a status is not explicit, do not assume it is satisfied.
169
169
  11. When `.agdf/control/` is missing or incomplete, make the next allowed artefact action explicit. For a fresh request, that means draft the minimal UR in the response, then request `Approval: UR`. Do not write a full control scaffold unless durable control state was explicitly requested or is already the repository's live AGDF working state.
170
170
  12. If branch, workspace and durable artefacts disagree, do not choose a scope silently; report the ambiguity and ask for the smallest clarifying gate action.
171
171
 
172
+ ### Scope Classification Output
173
+ When this skill classifies a fresh scope as ungated (Quick Task or Trivial Change Boundary), consume
174
+ `scope_classification.markdown` verbatim from `renderScopeClassificationCard` in
175
+ `../../meta/contracts/interaction.md` § Scope Classification Card. The card is a compact, localized,
176
+ non-authorizing projection: mode, boundary, UR-trigger evaluation, one allowed line, one forbidden
177
+ line, escalation triggers and the challenge path. Do not maintain or render a skill-local
178
+ classification card template. If the renderer returns `null`, fail closed to the existing ceremony
179
+ and do not model-reconstruct Markdown.
180
+
172
181
  ## Output
173
182
  Keep the result short and operational. For a status-only response, consume the Runtime Contract's
174
183
  code-owned `status_presentation.markdown` verbatim. It is the compact localized operational Run
@@ -349,6 +349,69 @@ export function renderOperationalStatusCard(statusCard, {
349
349
  });
350
350
  }
351
351
 
352
+ export function renderScopeClassificationCard(classification, {
353
+ registry,
354
+ requestedLocale,
355
+ } = {}) {
356
+ if (!plainObject(classification)) return null;
357
+ const outcome = String(classification.outcome ?? "").trim();
358
+ const mode = String(classification.mode ?? "").trim();
359
+ const trivialBoundary = String(classification.trivial_boundary ?? "").trim();
360
+ const urTriggerEvaluation = String(classification.ur_trigger_evaluation ?? "").trim();
361
+ const allowedSummary = String(classification.allowed_summary ?? "").trim();
362
+ const forbiddenSummary = String(classification.forbidden_summary ?? "").trim();
363
+ const escalationTriggers = Array.isArray(classification.escalation_triggers)
364
+ ? classification.escalation_triggers.map((item) => String(item ?? "").trim()).filter(Boolean)
365
+ : [];
366
+ const challengePath = String(classification.challenge_path ?? "").trim();
367
+
368
+ if (outcome !== "ungated") return null;
369
+ if (!["quick_task", "verified_change"].includes(mode)) return null;
370
+ if (!["inside", "outside"].includes(trivialBoundary)) return null;
371
+ if (!urTriggerEvaluation || !allowedSummary || !forbiddenSummary || !challengePath) return null;
372
+ if (escalationTriggers.length === 0) return null;
373
+
374
+ let locale;
375
+ try {
376
+ locale = resolvePresentationLocale(registry, requestedLocale);
377
+ } catch {
378
+ return null;
379
+ }
380
+ if (!locale) return null;
381
+
382
+ const pack = localePack(registry, locale);
383
+ const labels = pack?.scopeClassification;
384
+ if (!plainObject(labels)) return null;
385
+
386
+ const modeLabel = labels.mode?.[mode] ?? mode;
387
+ const boundaryLabel = labels.boundary?.[trivialBoundary] ?? trivialBoundary;
388
+
389
+ const rows = [
390
+ [labels.classification, `${modeLabel} · ${boundaryLabel}`],
391
+ [labels.grounds, urTriggerEvaluation],
392
+ [labels.allowed, allowedSummary],
393
+ [labels.forbidden, forbiddenSummary],
394
+ [labels.escalation, escalationTriggers.join("; ")],
395
+ [labels.challenge, challengePath],
396
+ ];
397
+
398
+ const markdown = [
399
+ `## ${labels.title ?? "AGDF scope classification"}`,
400
+ "",
401
+ `| ${labels.field ?? "Field"} | ${labels.value ?? "Value"} |`,
402
+ "|---|---|",
403
+ ...rows.map(([label, value]) => `| ${markdownCell(label)} | ${markdownCell(value)} |`),
404
+ ].join("\n");
405
+
406
+ return Object.freeze({
407
+ schema_version: "1",
408
+ semantic_block: "scope_classification_card",
409
+ presentation_language: locale,
410
+ markdown,
411
+ authorizes: false,
412
+ });
413
+ }
414
+
352
415
  export function gateOptions(registry, requestedLocale, gate, { includeCancel = false } = {}) {
353
416
  const pack = localePack(registry, requestedLocale);
354
417
  const options = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agdf",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "Bootstrap AGDF repository-local plugin files, Copilot/OpenCode instructions, skills, control files and machine-readable checks.",
5
5
  "type": "module",
6
6
  "files": [