create-agdf 0.8.3 → 0.8.4

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.
@@ -2259,10 +2259,14 @@ function buildStatusCard({
2259
2259
  const qualityOutlook = deriveQualityOutlook(runState, findings);
2260
2260
  const postApproval = postApprovalTransition(missingApproval);
2261
2261
  const isUserGateApproval = missingApproval !== "none";
2262
+ const lifecycle = extractField(runState.content ?? "", "lifecycle") || "unknown";
2263
+ const nativeAttemptRequired = status === "open" && isUserGateApproval;
2262
2264
  return {
2263
2265
  run_id: extractField(runState.content ?? "", "run_id") || "unknown",
2264
2266
  presentation_language: chatLanguage,
2265
2267
  mode: extractField(runState.content ?? "", "mode") || "unknown",
2268
+ lifecycle,
2269
+ delivery_state: lifecycle === "completed" && currentGate === "OR" ? "completed_closeout_pending" : lifecycle,
2266
2270
  status,
2267
2271
  current_gate: currentGate,
2268
2272
  mode_slice_decision: runState.mode_slice_decision?.decision || "undecided",
@@ -2280,6 +2284,8 @@ function buildStatusCard({
2280
2284
  next_skill: nextSkillByGate[currentGate] ?? "gate-check",
2281
2285
  next_step: nextAllowedAction,
2282
2286
  quality_outlook: qualityOutlook,
2287
+ interaction_kind: nativeAttemptRequired ? "gate_approval" : status === "blocked" ? "blocked" : "status",
2288
+ native_attempt_required: nativeAttemptRequired,
2283
2289
  };
2284
2290
  }
2285
2291
 
@@ -2736,6 +2742,8 @@ function evaluateGateCheck(targetDir, selection = {}) {
2736
2742
  doctor_summary: doctorReport.summary,
2737
2743
  evidence_refs: runState.evidence_refs,
2738
2744
  quality_outlook: deriveQualityOutlook(runState, deliveryMap.findings),
2745
+ interaction_kind: statusCard.interaction_kind,
2746
+ native_attempt_required: statusCard.native_attempt_required,
2739
2747
  candidate_runs: runState.candidate_runs ?? [],
2740
2748
  status_card: statusCard,
2741
2749
  delivery_map: {
@@ -2764,6 +2772,7 @@ function printGateCheckStatusCard(report) {
2764
2772
  console.log(`${labels.run}: ${card.run_id}`);
2765
2773
  console.log(`${labels.humanTitle}: ${presentation.runTitle}`);
2766
2774
  console.log(`${labels.gate}: ${card.current_gate} — ${presentation.gateTitle}`);
2775
+ console.log(`${labels.lifecycle}: ${primary.lifecycle[card.delivery_state] ?? primary.lifecycle.unknown}`);
2767
2776
  console.log(`${labels.artefacts}: ${formatArtefactRefs(presentation.artefactRefs)}`);
2768
2777
  console.log(`${labels.blocked}: ${card.blocking_condition === "none" ? primary.none : primary.blocked}`);
2769
2778
  console.log(`${labels.missing}: ${card.missing_approval === "none" ? primary.none : card.missing_approval}`);
@@ -75,6 +75,12 @@ For a ready `gate_approval`:
75
75
  13. Reject a missing artefact, ambiguous or wrong run, wrong gate, stale expected gate, timeout/default, hook-supplied answer, agent message, technical permission outcome or plan approval.
76
76
  14. Persist accepted input only through the existing control-state workflow.
77
77
 
78
+ The ready-gate projection must expose `native_attempt_required: true`. Treat this as a mandatory
79
+ orchestration instruction: after rendering the two cards, invoke the configured native question
80
+ adapter exactly once before using the exact-text fallback. A hook, permission result or session
81
+ context message cannot replace that attempt or supply its answer. For every non-ready interaction,
82
+ the signal is absent or false and no approval control may be shown.
83
+
78
84
  Before composing the question, resolve the configured chat locale from `.agdf/control/config.json` through `../agdf-interaction-locales.json`: exact complete pack, language subtag, then English fallback. German and English are initial packs, not a closed language list. Keep `Approval: <GateName>` exactly unchanged in every language, and do not mix presentation languages within one interaction. Labels and descriptions use the same resolved locale; host-owned UI chrome remains host-owned and may use a different language.
79
85
 
80
86
  For the transition card, use the complete resolved locale pack. The initial German pack includes `Bereit für deine Entscheidung`, `Jetzt freigeben` and `Danach`; the initial English pack includes `Ready for your decision`, `Approve now` and `Next`. Keep each card in one locale. Use a localized human-readable gate title rather than an internal status label, while leaving the exact gate identifier and approval value unchanged. Do not render a Markdown table, dashboard rows, raw control-state keys, diagnostic codes, evidence lists, a duplicated gate question or a false user gate in the approval-time card.
@@ -25,6 +25,7 @@
25
25
  "skill": "Next skill",
26
26
  "step": "Next step",
27
27
  "quality": "Quality outlook",
28
+ "lifecycle": "Delivery status",
28
29
  "allowed": "Allowed now",
29
30
  "forbidden": "Forbidden now",
30
31
  "artefacts": "Artefacts"
@@ -91,6 +92,13 @@
91
92
  "none": "none",
92
93
  "blocked": "current gate prerequisites",
93
94
  "quality": "Keep the presentation contract, evidence and gate authority aligned.",
95
+ "lifecycle": {
96
+ "active": "in progress",
97
+ "completed_closeout_pending": "completed — delivery closeout pending",
98
+ "completed": "completed",
99
+ "blocked": "blocked",
100
+ "unknown": "status not available"
101
+ },
94
102
  "actions": {
95
103
  "UR": "Clarify and approve the user requirements.",
96
104
  "Brownfield Review": "Review existing owners and choose the smallest safe delivery path.",
@@ -132,6 +140,7 @@
132
140
  "skill": "Nächster Skill",
133
141
  "step": "Nächster Schritt",
134
142
  "quality": "Qualitätsausblick",
143
+ "lifecycle": "Lieferstatus",
135
144
  "allowed": "Jetzt erlaubt",
136
145
  "forbidden": "Aktuell verboten",
137
146
  "artefacts": "Artefakte"
@@ -198,6 +207,13 @@
198
207
  "none": "keine",
199
208
  "blocked": "Voraussetzungen des aktuellen Gates",
200
209
  "quality": "Präsentationsvertrag, Nachweise und Gate-Berechtigung konsistent halten.",
210
+ "lifecycle": {
211
+ "active": "in Arbeit",
212
+ "completed_closeout_pending": "abgeschlossen — Abschluss offen",
213
+ "completed": "abgeschlossen",
214
+ "blocked": "blockiert",
215
+ "unknown": "Status nicht verfügbar"
216
+ },
201
217
  "actions": {
202
218
  "UR": "Nutzeranforderungen klären und freigeben.",
203
219
  "Brownfield Review": "Bestehende Owner prüfen und den kleinsten sicheren Lieferweg wählen.",
@@ -390,6 +390,7 @@ interaction_kind: clarification | tool_permission | gate_approval | blocked | st
390
390
  surface: codex | claude | opencode | fallback
391
391
  run_id: required for gate_approval
392
392
  current_gate: required for gate_approval
393
+ native_attempt_required: true only for an eligible gate_approval before the first adapter attempt
393
394
  prompt: required
394
395
  options: required for a structured question
395
396
  effects: required when the interaction can cause side effects
@@ -420,6 +421,12 @@ Before presenting `gate_approval`, the agent must:
420
421
  6. reject missing evidence, ambiguous or wrong run, wrong gate, stale state and any response that is no longer valid;
421
422
  7. persist an accepted approval only through the existing control-state workflow.
422
423
 
424
+ For an eligible `gate_approval`, `native_attempt_required` is a mandatory orchestration signal. The
425
+ agent must make exactly one configured native adapter attempt after the two orientation cards and
426
+ before any exact-text fallback. Hooks may prepare context but must not answer, approve or replace
427
+ the adapter attempt. The signal is absent or false for clarification, blocked, status-only,
428
+ internal-step and non-ready interactions.
429
+
423
430
  The first eligible native-attempt has a single bounded outcome: the declared
424
431
  host control is presented, or the agent immediately uses the exact-text
425
432
  fallback. A host that does not apply the control does not trigger a second
@@ -25,6 +25,7 @@
25
25
  "skill": "Next skill",
26
26
  "step": "Next step",
27
27
  "quality": "Quality outlook",
28
+ "lifecycle": "Delivery status",
28
29
  "allowed": "Allowed now",
29
30
  "forbidden": "Forbidden now",
30
31
  "artefacts": "Artefacts"
@@ -91,6 +92,13 @@
91
92
  "none": "none",
92
93
  "blocked": "current gate prerequisites",
93
94
  "quality": "Keep the presentation contract, evidence and gate authority aligned.",
95
+ "lifecycle": {
96
+ "active": "in progress",
97
+ "completed_closeout_pending": "completed — delivery closeout pending",
98
+ "completed": "completed",
99
+ "blocked": "blocked",
100
+ "unknown": "status not available"
101
+ },
94
102
  "actions": {
95
103
  "UR": "Clarify and approve the user requirements.",
96
104
  "Brownfield Review": "Review existing owners and choose the smallest safe delivery path.",
@@ -132,6 +140,7 @@
132
140
  "skill": "Nächster Skill",
133
141
  "step": "Nächster Schritt",
134
142
  "quality": "Qualitätsausblick",
143
+ "lifecycle": "Lieferstatus",
135
144
  "allowed": "Jetzt erlaubt",
136
145
  "forbidden": "Aktuell verboten",
137
146
  "artefacts": "Artefakte"
@@ -198,6 +207,13 @@
198
207
  "none": "keine",
199
208
  "blocked": "Voraussetzungen des aktuellen Gates",
200
209
  "quality": "Präsentationsvertrag, Nachweise und Gate-Berechtigung konsistent halten.",
210
+ "lifecycle": {
211
+ "active": "in Arbeit",
212
+ "completed_closeout_pending": "abgeschlossen — Abschluss offen",
213
+ "completed": "abgeschlossen",
214
+ "blocked": "blockiert",
215
+ "unknown": "Status nicht verfügbar"
216
+ },
201
217
  "actions": {
202
218
  "UR": "Nutzeranforderungen klären und freigeben.",
203
219
  "Brownfield Review": "Bestehende Owner prüfen und den kleinsten sicheren Lieferweg wählen.",
@@ -390,6 +390,7 @@ interaction_kind: clarification | tool_permission | gate_approval | blocked | st
390
390
  surface: codex | claude | opencode | fallback
391
391
  run_id: required for gate_approval
392
392
  current_gate: required for gate_approval
393
+ native_attempt_required: true only for an eligible gate_approval before the first adapter attempt
393
394
  prompt: required
394
395
  options: required for a structured question
395
396
  effects: required when the interaction can cause side effects
@@ -420,6 +421,12 @@ Before presenting `gate_approval`, the agent must:
420
421
  6. reject missing evidence, ambiguous or wrong run, wrong gate, stale state and any response that is no longer valid;
421
422
  7. persist an accepted approval only through the existing control-state workflow.
422
423
 
424
+ For an eligible `gate_approval`, `native_attempt_required` is a mandatory orchestration signal. The
425
+ agent must make exactly one configured native adapter attempt after the two orientation cards and
426
+ before any exact-text fallback. Hooks may prepare context but must not answer, approve or replace
427
+ the adapter attempt. The signal is absent or false for clarification, blocked, status-only,
428
+ internal-step and non-ready interactions.
429
+
423
430
  The first eligible native-attempt has a single bounded outcome: the declared
424
431
  host control is presented, or the agent immediately uses the exact-text
425
432
  fallback. A host that does not apply the control does not trigger a second
@@ -75,6 +75,12 @@ For a ready `gate_approval`:
75
75
  13. Reject a missing artefact, ambiguous or wrong run, wrong gate, stale expected gate, timeout/default, hook-supplied answer, agent message, technical permission outcome or plan approval.
76
76
  14. Persist accepted input only through the existing control-state workflow.
77
77
 
78
+ The ready-gate projection must expose `native_attempt_required: true`. Treat this as a mandatory
79
+ orchestration instruction: after rendering the two cards, invoke the configured native question
80
+ adapter exactly once before using the exact-text fallback. A hook, permission result or session
81
+ context message cannot replace that attempt or supply its answer. For every non-ready interaction,
82
+ the signal is absent or false and no approval control may be shown.
83
+
78
84
  Before composing the question, resolve the configured chat locale from `.agdf/control/config.json` through `../../agdf-interaction-locales.json`: exact complete pack, language subtag, then English fallback. German and English are initial packs, not a closed language list. Keep `Approval: <GateName>` exactly unchanged in every language, and do not mix presentation languages within one interaction. Labels and descriptions use the same resolved locale; host-owned UI chrome remains host-owned and may use a different language.
79
85
 
80
86
  For the transition card, use the complete resolved locale pack. The initial German pack includes `Bereit für deine Entscheidung`, `Jetzt freigeben` and `Danach`; the initial English pack includes `Ready for your decision`, `Approve now` and `Next`. Keep each card in one locale. Use a localized human-readable gate title rather than an internal status label, while leaving the exact gate identifier and approval value unchanged. Do not render a Markdown table, dashboard rows, raw control-state keys, diagnostic codes, evidence lists, a duplicated gate question or a false user gate in the approval-time card.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdf",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "Codex-first operating system for governed AI-assisted delivery.",
5
5
  "author": {
6
6
  "name": "Arndt Gold",
@@ -25,6 +25,7 @@
25
25
  "skill": "Next skill",
26
26
  "step": "Next step",
27
27
  "quality": "Quality outlook",
28
+ "lifecycle": "Delivery status",
28
29
  "allowed": "Allowed now",
29
30
  "forbidden": "Forbidden now",
30
31
  "artefacts": "Artefacts"
@@ -91,6 +92,13 @@
91
92
  "none": "none",
92
93
  "blocked": "current gate prerequisites",
93
94
  "quality": "Keep the presentation contract, evidence and gate authority aligned.",
95
+ "lifecycle": {
96
+ "active": "in progress",
97
+ "completed_closeout_pending": "completed — delivery closeout pending",
98
+ "completed": "completed",
99
+ "blocked": "blocked",
100
+ "unknown": "status not available"
101
+ },
94
102
  "actions": {
95
103
  "UR": "Clarify and approve the user requirements.",
96
104
  "Brownfield Review": "Review existing owners and choose the smallest safe delivery path.",
@@ -132,6 +140,7 @@
132
140
  "skill": "Nächster Skill",
133
141
  "step": "Nächster Schritt",
134
142
  "quality": "Qualitätsausblick",
143
+ "lifecycle": "Lieferstatus",
135
144
  "allowed": "Jetzt erlaubt",
136
145
  "forbidden": "Aktuell verboten",
137
146
  "artefacts": "Artefakte"
@@ -198,6 +207,13 @@
198
207
  "none": "keine",
199
208
  "blocked": "Voraussetzungen des aktuellen Gates",
200
209
  "quality": "Präsentationsvertrag, Nachweise und Gate-Berechtigung konsistent halten.",
210
+ "lifecycle": {
211
+ "active": "in Arbeit",
212
+ "completed_closeout_pending": "abgeschlossen — Abschluss offen",
213
+ "completed": "abgeschlossen",
214
+ "blocked": "blockiert",
215
+ "unknown": "Status nicht verfügbar"
216
+ },
201
217
  "actions": {
202
218
  "UR": "Nutzeranforderungen klären und freigeben.",
203
219
  "Brownfield Review": "Bestehende Owner prüfen und den kleinsten sicheren Lieferweg wählen.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "agdf",
4
- "version": "0.8.3",
4
+ "version": "0.8.4",
5
5
  "displayName": "AI Governance & Delivery Framework",
6
6
  "developerName": "Arndt Gold",
7
7
  "description": "Codex-first operating system for governed AI-assisted delivery.",
@@ -390,6 +390,7 @@ interaction_kind: clarification | tool_permission | gate_approval | blocked | st
390
390
  surface: codex | claude | opencode | fallback
391
391
  run_id: required for gate_approval
392
392
  current_gate: required for gate_approval
393
+ native_attempt_required: true only for an eligible gate_approval before the first adapter attempt
393
394
  prompt: required
394
395
  options: required for a structured question
395
396
  effects: required when the interaction can cause side effects
@@ -420,6 +421,12 @@ Before presenting `gate_approval`, the agent must:
420
421
  6. reject missing evidence, ambiguous or wrong run, wrong gate, stale state and any response that is no longer valid;
421
422
  7. persist an accepted approval only through the existing control-state workflow.
422
423
 
424
+ For an eligible `gate_approval`, `native_attempt_required` is a mandatory orchestration signal. The
425
+ agent must make exactly one configured native adapter attempt after the two orientation cards and
426
+ before any exact-text fallback. Hooks may prepare context but must not answer, approve or replace
427
+ the adapter attempt. The signal is absent or false for clarification, blocked, status-only,
428
+ internal-step and non-ready interactions.
429
+
423
430
  The first eligible native-attempt has a single bounded outcome: the declared
424
431
  host control is presented, or the agent immediately uses the exact-text
425
432
  fallback. A host that does not apply the control does not trigger a second
@@ -75,6 +75,12 @@ For a ready `gate_approval`:
75
75
  13. Reject a missing artefact, ambiguous or wrong run, wrong gate, stale expected gate, timeout/default, hook-supplied answer, agent message, technical permission outcome or plan approval.
76
76
  14. Persist accepted input only through the existing control-state workflow.
77
77
 
78
+ The ready-gate projection must expose `native_attempt_required: true`. Treat this as a mandatory
79
+ orchestration instruction: after rendering the two cards, invoke the configured native question
80
+ adapter exactly once before using the exact-text fallback. A hook, permission result or session
81
+ context message cannot replace that attempt or supply its answer. For every non-ready interaction,
82
+ the signal is absent or false and no approval control may be shown.
83
+
78
84
  Before composing the question, resolve the configured chat locale from `.agdf/control/config.json` through `plugin/meta/agdf-interaction-locales.json`: exact complete pack, language subtag, then English fallback. German and English are initial packs, not a closed language list. Keep `Approval: <GateName>` exactly unchanged in every language, and do not mix presentation languages within one interaction. Labels and descriptions use the same resolved locale; host-owned UI chrome remains host-owned and may use a different language.
79
85
 
80
86
  For the transition card, use the complete resolved locale pack. The initial German pack includes `Bereit für deine Entscheidung`, `Jetzt freigeben` and `Danach`; the initial English pack includes `Ready for your decision`, `Approve now` and `Next`. Keep each card in one locale. Use a localized human-readable gate title rather than an internal status label, while leaving the exact gate identifier and approval value unchanged. Do not render a Markdown table, dashboard rows, raw control-state keys, diagnostic codes, evidence lists, a duplicated gate question or a false user gate in the approval-time card.
@@ -147,6 +147,57 @@ export function buildRunCandidates(runs) {
147
147
  .sort((left, right) => left.display_title.localeCompare(right.display_title) || left.run_id.localeCompare(right.run_id));
148
148
  }
149
149
 
150
+ export function normalizeReconciliationText(value) {
151
+ return String(value ?? "")
152
+ .normalize("NFKC")
153
+ .toLowerCase()
154
+ .replace(/[._:/\\-]+/g, " ")
155
+ .replace(/[^\p{L}\p{N}\s]+/gu, " ")
156
+ .replace(/\s+/g, " ")
157
+ .trim();
158
+ }
159
+
160
+ export function reconcileRunScope({ requestText = "", scopeKey = "", runs = [] } = {}) {
161
+ const requested = normalizeReconciliationText(scopeKey || requestText);
162
+ if (!requested) return Object.freeze({ outcome: "match_uncertain", matches: [], reason: "scope_input_missing" });
163
+ const matches = [...(runs ?? [])]
164
+ .filter((run) => run?.valid && ["active", "completed"].includes(run?.meta?.lifecycle) && typeof run.run_id === "string")
165
+ .filter((run) => {
166
+ const keys = [run.scope_key, run.display_title, run.current_artefact_heading, run.ur_heading]
167
+ .map(normalizeReconciliationText)
168
+ .filter(Boolean);
169
+ return keys.includes(requested);
170
+ })
171
+ .map((run) => Object.freeze({
172
+ run_id: run.run_id,
173
+ lifecycle: run.meta.lifecycle,
174
+ display_title: displaySafeTitle(run.display_title || run.ur_heading || run.run_id, normalizedRunTitle(run.run_id)),
175
+ current_gate: run.control_state?.current_gate || run.meta?.current_gate || "unknown",
176
+ }))
177
+ .sort((left, right) => left.run_id.localeCompare(right.run_id));
178
+ if (matches.length !== 1) return Object.freeze({ outcome: matches.length ? "match_uncertain" : "no_match", matches, reason: matches.length > 1 ? "multiple_exact_matches" : "no_exact_match" });
179
+ return Object.freeze({ outcome: matches[0].lifecycle === "active" ? "active_match" : "completed_match", matches, reason: "exact_match" });
180
+ }
181
+
182
+ export function executeNativeApprovalAttempt({ ready = false, invokeNative, fallback } = {}) {
183
+ if (!ready) return Object.freeze({ attempted: false, outcome: "unavailable_before_invocation", reason: "gate_not_ready", authorizes: false });
184
+ if (typeof invokeNative !== "function") return Object.freeze({ attempted: false, outcome: "unavailable_before_invocation", reason: "adapter_unavailable", authorizes: false });
185
+ let adapterResult;
186
+ try {
187
+ adapterResult = invokeNative();
188
+ } catch (error) {
189
+ adapterResult = { outcome: "attempted_not_applied", reason: String(error?.message || "adapter_error") };
190
+ }
191
+ const outcome = ATTEMPT_OUTCOMES.has(adapterResult?.outcome)
192
+ ? adapterResult.outcome
193
+ : adapterResult?.presented === true || adapterResult?.applied === true
194
+ ? "presented"
195
+ : "attempted_not_applied";
196
+ const reason = String(adapterResult?.reason || "").trim();
197
+ if (outcome !== "presented" && typeof fallback === "function") fallback({ outcome, reason });
198
+ return Object.freeze({ attempted: true, outcome, reason, authorizes: false });
199
+ }
200
+
150
201
  export function buildInteractionAttempt({ interactionId, runId, currentGate, surface, attemptOutcome, expectedApproval, fallbackReason = "" }) {
151
202
  if (!ATTEMPT_OUTCOMES.has(attemptOutcome)) throw new Error("invalid interaction attempt outcome");
152
203
  if (!String(interactionId ?? "").trim() || !String(runId ?? "").trim() || !String(currentGate ?? "").trim())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agdf",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
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": [