feat: publish reviewed architecture and ADR batch
Some checks failed
Build and publish policy-nexus image / build-and-push (push) Failing after 19s
Some checks failed
Build and publish policy-nexus image / build-and-push (push) Failing after 19s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
This commit is contained in:
parent
023badb512
commit
93608c1f17
120 changed files with 17791 additions and 727 deletions
|
|
@ -1,7 +1,7 @@
|
|||
<!doctype html>
|
||||
<html lang="en"><meta charset="utf-8">
|
||||
<meta name="policy-source-revision" content="41a3fb8b81bd521a5fa21af114975c54532df3ad">
|
||||
<meta name="policy-source-digest" content="89b3a925d8cf6d9dbfe426980021b58281350201f316654b7fc1ee6554910ac6">
|
||||
<meta name="policy-source-revision" content="b72fdb5452bff51a867a0316edb994723b35f268">
|
||||
<meta name="policy-source-digest" content="92da58f58ee3dbb62233161a0fc0b7780920f81ec37fdd40d476be354f24e0eb">
|
||||
<title>The Producer Trust Boundary — Guardrails and Error-Correction for Untrusted Output</title>
|
||||
<style>
|
||||
:root{
|
||||
|
|
@ -191,7 +191,7 @@ a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-off
|
|||
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
|
||||
|
||||
</style>
|
||||
<div class="wrap"><header><div class="eyebrow"><span>ACT-ADR-004</span> <span class="stat">accepted · accepted-1</span> <span>activity-core</span> <span>reviewed 2026-06-26</span><span>generated from canonical source — do not edit</span></div><h1>The Producer Trust Boundary — Guardrails and Error-Correction for Untrusted Output</h1><p class="sub">Source: <code>activity-core · docs/adr/adr-004-producer-trust-boundary.md · 41a3fb8b81bd521a5fa21af114975c54532df3ad</code></p><p class="sub">Review due: 2026-12-26</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#status"><span class="n">·</span>Status</a></li><li><a href="#context"><span class="n">·</span>Context</a></li><li><a href="#decision"><span class="n">·</span>Decision</a></li><li><a href="#consequences"><span class="n">·</span>Consequences</a></li><li><a href="#alternatives-considered"><span class="n">·</span>Alternatives considered</a></li><li><a href="#references"><span class="n">·</span>References</a></li></ol></nav><main><section id="status"><h2>Status</h2>
|
||||
<div class="wrap"><header><div class="eyebrow"><span>ACT-ADR-004</span> <span class="stat">accepted · accepted-2</span> <span>activity-core</span> <span>reviewed 2026-06-26</span><span>generated from canonical source — do not edit</span></div><h1>The Producer Trust Boundary — Guardrails and Error-Correction for Untrusted Output</h1><p class="sub">Source: <code>activity-core · docs/adr/adr-004-producer-trust-boundary.md · b72fdb5452bff51a867a0316edb994723b35f268</code></p><p class="sub">Review due: 2026-12-26</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#status"><span class="n">·</span>Status</a></li><li><a href="#context"><span class="n">·</span>Context</a></li><li><a href="#decision"><span class="n">·</span>Decision</a></li><li><a href="#consequences"><span class="n">·</span>Consequences</a></li><li><a href="#alternatives-considered"><span class="n">·</span>Alternatives considered</a></li><li><a href="#references"><span class="n">·</span>References</a></li></ol></nav><main><section id="status"><h2>Status</h2>
|
||||
<p>Accepted.</p>
|
||||
</section>
|
||||
<section id="context"><h2>Context</h2>
|
||||
|
|
@ -209,7 +209,7 @@ a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-off
|
|||
<ol><li><strong>Push verification to the boundary; keep the interior strict.</strong> Apply posture <strong>B</strong> at the producer→consumer boundary; keep posture <strong>A</strong> for residual exceptions inside the verified core. Never relax the interior schema to absorb producer sloppiness.</li><li><strong>Make error locality match the unit of work.</strong> One bad recommendation must cost one recommendation, not the whole report. Structuring the payload so each item is independently parseable and validatable is the highest-leverage change.</li><li><strong>Quarantine, never silently drop.</strong> Invalid units are preserved as bounded, provenance-tagged artifacts (<code>index</code>, <code>error</code>, <code>raw</code> snippet, <code>reason</code>) so they can be debugged or replayed. Degraded-but-usable is reported distinctly from total loss.</li><li><strong>Both human and agent input get the same rigor.</strong> Guardrails are producer-agnostic: the same count / length / depth caps and reference allow-lists apply whether the producer is an LLM, an agent, or a human.</li></ol>
|
||||
<h3>What this means concretely in activity-core</h3>
|
||||
<p>Implemented in <code>src/activity_core/rules/executor.py</code>:</p>
|
||||
<ul><li><strong>Strict-structure-only schema.</strong> The daily-triage output schema is strict on per-item <em>structure</em> (<code>required [rank, candidate, action, why]</code>, typed <code>wsjf</code>) and carries <code>maxItems</code> as a producer <em>hint</em> — never as a hard whole-document reject, which would reproduce the very blast-radius failure (ACT-ADR-002 governs the schema format; <code>schemas/daily-triage-report.json</code>).</li><li><strong>Item-granular recovery (posture B).</strong> When whole-document parse + one retry fail, <code>_resilient_report</code> recovers individually-parseable recommendation objects via a brace/quote-aware scanner (<code>_extract_object_spans</code>) that works for both pretty-printed and NDJSON output, attempts a best-effort <code>_try_repair</code> on a truncated tail, validates each recovered object against the item schema, and keeps the valid ones. Survivors are emitted with <code>output_validated=true</code>, <code>partial=true</code>, and <code>review_required=true</code>.</li><li><strong>Producer guardrails (<code>_partition_items</code>, applied on both the recovery and the happy path).</strong> Per recommendation: structural type → schema → structural caps (<code>_MAX_DEPTH</code>, <code>_MAX_STRING_LEN</code>) → reference allow-list → count cap (top-N by <code>maxItems</code>). The first failing check quarantines the item with provenance and a <code>reason</code> (<code>malformed</code> / <code>schema</code> / <code>guardrail</code> / <code>allow_list</code> / <code>over_limit</code>).</li><li><strong>Reference allow-list.</strong> A recommendation whose <code>candidate</code> is not in the set of known ids is quarantined. The set is sourced from resolved context (<code>context["known_candidates"]</code>, via <code>_allow_list_from_context</code>); the check is inert until a context resolver populates it, so the capability ships now and activates with a one-line resolver change.</li></ul>
|
||||
<ul><li><strong>Strict-structure-only schema.</strong> The daily-triage output schema is strict on per-item <em>structure</em> (<code>required [rank, candidate, action, why]</code>, typed <code>wsjf</code>) and carries <code>maxItems</code> as a producer <em>hint</em> — never as a hard whole-document reject, which would reproduce the very blast-radius failure (ACT-ADR-002 governs the schema format; <code>schemas/daily-triage-report.json</code>).</li><li><strong>Item-granular recovery (posture B).</strong> When whole-document parse + one retry fail, <code>_resilient_report</code> recovers individually-parseable recommendation objects via a brace/quote-aware scanner (<code>_extract_object_spans</code>) that works for both pretty-printed and NDJSON output, attempts a best-effort <code>_try_repair</code> on a truncated tail, validates each recovered object against the item schema, and keeps the valid ones. Survivors are emitted with <code>output_validated=true</code>, <code>partial=true</code>, and <code>review_advisory=true</code> (<code>review_gate_applied=false</code>).</li><li><strong>Producer guardrails (<code>_partition_items</code>, applied on both the recovery and the happy path).</strong> Per recommendation: structural type → schema → structural caps (<code>_MAX_DEPTH</code>, <code>_MAX_STRING_LEN</code>) → reference allow-list → count cap (top-N by <code>maxItems</code>). The first failing check quarantines the item with provenance and a <code>reason</code> (<code>malformed</code> / <code>schema</code> / <code>guardrail</code> / <code>allow_list</code> / <code>over_limit</code>).</li><li><strong>Reference allow-list.</strong> A recommendation whose <code>candidate</code> is not in the set of known ids is quarantined. The set is sourced from resolved context (<code>context["known_candidates"]</code>, via <code>_allow_list_from_context</code>); the check is inert until a context resolver populates it, so the capability ships now and activates with a one-line resolver change.</li></ul>
|
||||
<h3>Where each posture sits</h3>
|
||||
<div class="scroll"><table><thead><tr><th>Layer</th><th>Posture</th><th>Mechanism</th></tr></thead><tbody><tr><td>Schema / contract</td><td>B</td><td>strict per-item structure; <code>maxItems</code> as hint</td></tr><tr><td>Whole-document parse</td><td>A</td><td>tolerant parse + single retry</td></tr><tr><td>Failed parse</td><td>B</td><td>item-granular recovery + repair + quarantine</td></tr><tr><td>Per-item screening</td><td>B</td><td>schema + depth/length caps + allow-list + count cap</td></tr><tr><td>Emitted report</td><td>—</td><td><code>partial</code> / <code>quarantined_*</code> provenance; never silent</td></tr></tbody></table></div>
|
||||
</section>
|
||||
|
|
@ -221,4 +221,4 @@ a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-off
|
|||
</section>
|
||||
<section id="references"><h2>References</h2>
|
||||
<ul><li>ACT-ADR-002 — markdown-as-definition format and output schema governance.</li><li>ACT-ADR-003 — Rule vs. Instruction model; the Instruction prompt-injection surface this boundary complements on the output side.</li><li><code>workplans/ACTIVITY-WP-0016-llm-output-robustness-trust-boundary.md</code> — the implementing workplan.</li></ul>
|
||||
</section><footer><span>ACT-ADR-004 · accepted-1 · accepted</span><span>activity-core · docs/adr/adr-004-producer-trust-boundary.md · 41a3fb8b81bd521a5fa21af114975c54532df3ad</span></footer></main></div></div></html>
|
||||
</section><footer><span>ACT-ADR-004 · accepted-2 · accepted</span><span>activity-core · docs/adr/adr-004-producer-trust-boundary.md · b72fdb5452bff51a867a0316edb994723b35f268</span></footer></main></div></div></html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue