Skip to content

Commit b136f9b

Browse files
authored
Generate completion reports deterministically (#175)
* Generate Docs Agent completion reports on host * Pin deterministic completion validator * Harden completion artifact staging * Pin hardened completion validator
1 parent f887e39 commit b136f9b

7 files changed

Lines changed: 190 additions & 516 deletions

.github/workflows/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ Schedule skills upkeep separately from docs upkeep. The skills lane should use a
1010

1111
When validation setup, verification commands, or drift checks are needed, pass them through the reusable workflow inputs above. `validation_dependencies` is an optional caller-owned command that runs before verification during a live execution. The reusable workflow includes those executable inputs in the portable recipe and keeps the target repository as the writable Docs Agent workspace.
1212

13-
Maintenance permits an evidence-backed no-op only for a non-empty caller-bounded `source_delta`. Every delta item must have source refs and a matching evidence-backed report item that covers them; exactly one versioned report from the canonical native transcript must agree with the host diff. Bootstrap may instead use inventory mode with its positive contract. Set `require_pr: true` for changed maintenance that must produce a valid target-repository PR; bootstrap changes always require publication.
13+
Maintenance permits a no-op only for a non-empty caller-bounded `source_delta`. The completion validator derives the report from those validated records, the host Git diff, writable paths, and filesystem bootstrap checks; model final prose is supplementary transcript evidence only. Bootstrap uses inventory mode with its positive contract. Set `require_pr: true` for changed maintenance that must produce a valid target-repository PR; bootstrap changes always require publication.
1414

15-
The reusable workflow declares the expected typed review artifacts for Docs Agent runs: transcript, change summary, verification report, drift report, completion report, and workspace publication links. `maintain-docs.yml` writes those declarations into the portable recipe and exposes the declaration objects through `declared_artifacts_json`. The completion runtime declaration remains optional for producer lifecycle compatibility, but the final completion drift command has a mandatory generic `{name,type,path}` artifact output. The Docs Agent-owned validator reads the report from the canonical transcript, compares it with the applied host diff, writes canonical bytes under `.codebox/agent-task-artifacts`, and WP Codebox stages only that validated declared artifact for review.
15+
The reusable workflow declares the expected typed review artifacts for Docs Agent runs: transcript, change summary, verification report, drift report, completion report, and workspace publication links. `maintain-docs.yml` writes those declarations into the portable recipe and exposes the declaration objects through `declared_artifacts_json`. The completion runtime declaration remains optional for producer lifecycle compatibility, but the final completion drift command has a mandatory generic `{name,type,path}` artifact output. The Docs Agent-owned validator generates canonical host-observed bytes under `.codebox/agent-task-artifacts`, and WP Codebox stages only that declared artifact for review.
1616

1717
The target repository grants `contents: write`, `pull-requests: write`, and `issues: write`. Docs Agent forwards the caller-scoped `${{ github.token }}` to WP Codebox for same-repository publication, so consumers do not configure `ACCESS_TOKEN`. `OPENAI_API_KEY` is an optional workflow secret and is required only for a live OpenAI run; skipped and dry-run calls do not require it. `EXTERNAL_PACKAGE_SOURCE_POLICY` remains a separate required v1 JSON secret. Migrate its value to the exact one-line JSON in the root README: it authorizes the selected Docs Agent package, the pinned Agents API component, the pinned PHP AI Client overlay, and the checksum-pinned OpenAI provider artifact. Both secrets are forwarded to WP Codebox without serialization into the task descriptor.
1818

.github/workflows/maintain-docs.yml

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ env:
44
# Advance this revision and all package digests together when package bytes change.
55
DOCS_AGENT_PACKAGE_REVISION: a39d9db230eb9e0b72ed84465f4d61bd8dda1bab
66
# Advance independently when the post-command completion validator changes.
7-
DOCS_AGENT_COMPLETION_CONTRACT_REVISION: a39d9db230eb9e0b72ed84465f4d61bd8dda1bab
7+
DOCS_AGENT_COMPLETION_CONTRACT_REVISION: 44f1e60e9278dd351fafea53434999de4782514b
88

99
'on':
1010
workflow_call:
@@ -242,30 +242,18 @@ jobs:
242242
{"schema":"docs-agent/artifact-declaration/v1","name":"docs_agent_change_summary","type":"DocsAgentChangeSummary","artifact_schema":"docs-agent/change-summary/v1","description":"Reviewable summary of documentation or skill changes made by the run.","required":false},
243243
{"schema":"docs-agent/artifact-declaration/v1","name":"docs_agent_verification_report","type":"DocsAgentVerificationReport","artifact_schema":"docs-agent/verification-report/v1","description":"Runner verification command results for the target workspace.","required":false},
244244
{"schema":"docs-agent/artifact-declaration/v1","name":"docs_agent_drift_report","type":"DocsAgentDriftReport","artifact_schema":"docs-agent/drift-report/v1","description":"Drift-check results for generated documentation, skills, or packaged outputs.","required":false},
245-
{"schema":"docs-agent/artifact-declaration/v1","name":"docs_agent_completion_report","type":"DocsAgentCompletionReport","artifact_schema":"docs-agent/completion-report/v1","description":"Versioned completion and drift report validated from the canonical native transcript and staged by WP Codebox.","required":false},
245+
{"schema":"docs-agent/artifact-declaration/v1","name":"docs_agent_completion_report","type":"DocsAgentCompletionReport","artifact_schema":"docs-agent/completion-report/v1","description":"Versioned host-observed completion and drift report staged by WP Codebox.","required":false},
246246
{"schema":"docs-agent/artifact-declaration/v1","name":"docs_agent_workspace_publication","type":"DocsAgentWorkspacePublication","artifact_schema":"docs-agent/workspace-publication/v1","description":"Canonical branch and pull request links published by the runner workspace.","required":false}
247247
]'
248248
249249
context_prompt="$(printf '%s' "$context_repositories" | jq -r 'if length == 0 then "No additional context repositories are declared." else "Read-only context repositories (cite aliases in evidence):\n" + (map("- " + .alias + ": " + .repository + "@" + .revision) | join("\n")) end')"
250-
completion_prompt="$(jq -nr --arg lane "$AUDIENCE" --arg run_kind "$RUN_KIND" --argjson bootstrap "$bootstrap_contract" --argjson delta "$source_delta" '
251-
($delta | map(.source_refs) | add // ["repository inventory"]) as $source_refs |
252-
(if $run_kind == "maintenance" then
253-
($delta | map({id,source_refs,documentation_paths:["docs/example.md"],disposition:(if .requires_documentation_change then "updated" else "verified_current" end),evidence:"Describe the source comparison and documentation decision."}))
254-
else
255-
[{id:"inventory",source_refs:$source_refs,documentation_paths:["README.md","docs/README.md"],disposition:"updated",evidence:"Describe the repository inventory and resulting documentation system."}]
256-
end) as $items |
257-
({schema:"docs-agent/completion-report/v1",lane:$lane,run_kind:$run_kind,outcome:"changes",scope:{source_basis:(if $run_kind == "maintenance" then "bounded_delta" else "inventory" end),source_refs:$source_refs,documentation_surfaces:["README.md","docs/example.md"]},items:$items,changed_paths:["docs/example.md"]}|tojson) as $report_shape |
258-
"Completion contract (mandatory):\n" +
259-
"- End with exactly one <DOCS_AGENT_COMPLETION_REPORT>{JSON}</DOCS_AGENT_COMPLETION_REPORT> block and no other report block.\n" +
260-
"- Return valid compact JSON with double-quoted keys and strings, no markdown fence, no comments, no placeholders, and no trailing commas.\n" +
261-
"- JSON schema: docs-agent/completion-report/v1; lane=" + $lane + "; run_kind=" + $run_kind + ".\n" +
262-
"- Include outcome (changes or no_changes), scope.source_basis, non-empty scope.source_refs and scope.documentation_surfaces, non-empty evidence-backed per-item dispositions, and changed_paths.\n" +
263-
"- Maintenance must use bounded_delta and cover every caller source_delta ID and source ref in its matching evidence-backed report item. Bootstrap may use inventory with its positive bootstrap contract.\n" +
264-
"- changed_paths must exactly match workspace_git_status/workspace_git_diff. A write call without a byte diff is not a change.\n" +
265-
"- For no_changes, use only verified_current or not_documentation_relevant dispositions, cover every bounded source delta, and leave the documentation diff clean.\n" +
266-
"- For changes, use created/updated dispositions and report every actual changed path. Never write outside writable paths.\n" +
250+
completion_prompt="$(jq -nr --argjson bootstrap "$bootstrap_contract" --argjson delta "$source_delta" '
251+
"Completion contract:\n" +
252+
"- Interpret the caller-known source delta and edit only within writable paths when source evidence requires documentation updates.\n" +
253+
"- Leave the workspace clean when the documentation is current.\n" +
254+
"- Every source delta marked requires_documentation_change needs an actual Markdown or MDX workspace diff.\n" +
267255
"- Bootstrap must satisfy every caller criterion and create a substantive navigable initial documentation system on a fresh surface.\n" +
268-
"Exact report shape (replace example documentation paths, evidence, dispositions, outcome, and changed_paths with verified values; preserve caller IDs and source refs):\n<DOCS_AGENT_COMPLETION_REPORT>" + $report_shape + "</DOCS_AGENT_COMPLETION_REPORT>\n" +
256+
"- The host generates and stages the completion report from caller inputs, Git, and filesystem checks; finish with normal concise prose.\n" +
269257
"Bootstrap contract JSON: " + ($bootstrap|tojson) + "\n" +
270258
"Caller-known source delta JSON: " + ($delta|tojson)
271259
')"
@@ -322,7 +310,7 @@ jobs:
322310
bootstrap_contract_b64="$(printf '%s' "$bootstrap_contract" | base64 -w0)"
323311
source_delta_b64="$(printf '%s' "$source_delta" | base64 -w0)"
324312
completion_artifact_path="docs-agent-completion-report.json"
325-
completion_command="curl --fail --silent --show-error '$contract_url' --output .codebox/validate-docs-agent-completion.php && php .codebox/validate-docs-agent-completion.php --workspace . --lane '$AUDIENCE' --run-kind '$RUN_KIND' --writable-paths '$INPUT_WRITABLE_PATHS' --bootstrap-contract-b64 '$bootstrap_contract_b64' --source-delta-b64 '$source_delta_b64' --transcript-root .codebox/agent-task-artifacts --artifact-path '$completion_artifact_path'"
313+
completion_command="curl --fail --silent --show-error '$contract_url' --output .codebox/validate-docs-agent-completion.php && php .codebox/validate-docs-agent-completion.php --workspace . --lane '$AUDIENCE' --run-kind '$RUN_KIND' --writable-paths '$INPUT_WRITABLE_PATHS' --bootstrap-contract-b64 '$bootstrap_contract_b64' --source-delta-b64 '$source_delta_b64' --artifact-path '$completion_artifact_path'"
326314
completion_check="$(jq -cn --arg command "$completion_command" --arg path "$completion_artifact_path" '{command:$command,description:"Validate Docs Agent completion report against the actual workspace diff",artifact:{name:"docs_agent_completion_report",type:"DocsAgentCompletionReport",path:$path}}')"
327315
effective_drift_checks="$(jq -cn --argjson caller "$drift_checks" --argjson completion "$completion_check" '$caller + [$completion]')"
328316
allowed_repos="$(printf '%s' "$context_repositories" | jq -c --arg target "$GITHUB_REPOSITORY_NAME" '([$target] + map(.repository)) | unique')"

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ Docs Agent declares the review artifacts it expects the runner to materialize as
129129
| `docs_agent_change_summary` | `docs-agent/change-summary/v1` | Reviewable summary of documentation or skill changes. |
130130
| `docs_agent_verification_report` | `docs-agent/verification-report/v1` | Verification command results for the target workspace. |
131131
| `docs_agent_drift_report` | `docs-agent/drift-report/v1` | Drift-check results for generated docs, skills, or packaged outputs. |
132-
| `docs_agent_completion_report` | `docs-agent/completion-report/v1` | Native completion and source-to-document disposition report validated against the host diff. |
132+
| `docs_agent_completion_report` | `docs-agent/completion-report/v1` | Host-observed completion report generated from caller inputs, Git, and filesystem checks. |
133133
| `docs_agent_workspace_publication` | `docs-agent/workspace-publication/v1` | Canonical branch and pull request links published by the runner workspace. |
134134

135-
`maintain-docs.yml` writes `expected_artifacts` and `artifact_declarations` into a portable Docs Agent recipe and exposes the same declaration objects as `declared_artifacts_json`. The runtime declaration for `docs_agent_completion_report` remains `required: false` because WP Codebox may evaluate runtime-level required artifacts before post-command validation. The final completion drift entry is mandatory and declares `{name,type,path}`; after successful semantic validation, the validator atomically writes canonical JSON to `.codebox/agent-task-artifacts/docs-agent-completion-report.json`, and WP Codebox stages that declared command artifact for reviewers.
135+
`maintain-docs.yml` writes `expected_artifacts` and `artifact_declarations` into a portable Docs Agent recipe and exposes the same declaration objects as `declared_artifacts_json`. The runtime declaration for `docs_agent_completion_report` remains `required: false` because WP Codebox may evaluate runtime-level required artifacts before post-command validation. The final completion drift entry is mandatory and declares `{name,type,path}`; after deterministic host validation, the validator atomically writes canonical JSON to `.codebox/agent-task-artifacts/docs-agent-completion-report.json`, and WP Codebox stages that declared command artifact for reviewers.
136136

137137
The reusable workflow and helper implementation are pinned to accepted revision `a6fe2d208e990a8d04104aa74aacbb8d1539fbc1`; `v0.12.29` remains only the `wp_codebox_release_ref` for released packaged runtime assets at `bc982947ec33c78160125026e16d357b7ece3ea1`.
138138

@@ -147,25 +147,25 @@ Portable recipe fields include `docsAgent`, `runner.contextRepositories`, `runne
147147
A live run succeeds only when four independent layers pass:
148148

149149
1. Agents API completes the selected native package through WP Codebox.
150-
2. Docs Agent validates exactly one `docs-agent/completion-report/v1` from the canonical transcript against the actual host workspace diff and writable paths.
150+
2. Docs Agent generates `docs-agent/completion-report/v1` from validated caller inputs, actual host workspace changes, writable paths, and bootstrap filesystem checks.
151151
3. Caller dependency, verification, and drift commands pass.
152152
4. WP Codebox publishes and verifies a pull request when the outcome and caller policy require one.
153153

154-
For `changes`, `changed_paths` must exactly equal the Git diff, every path must be writable, and at least one evidence-backed item must be `created` or `updated`. A write-tool call that leaves no byte diff fails as `CHANGES_DIFF_EMPTY`.
154+
For `changes`, `changed_paths` exactly equals the Git diff and every path must be writable. A write-tool call that leaves no byte diff produces `no_changes`.
155155

156-
For every maintenance outcome, `source_delta` must be non-empty and caller-bounded: each item has a unique ID and non-empty source refs, the report uses `bounded_delta`, and its matching evidence-backed item covers every declared ref. For maintenance `no_changes`, the documentation diff must also be clean and dispositions may only be `verified_current` or `not_documentation_relevant`. Caller-known drift marked `requires_documentation_change: true` cannot be reported as no-change. Bootstrap may instead use `inventory` with its required positive bootstrap contract. Missing, malformed, empty, incomplete, contradictory, diff-mismatched, and out-of-scope reports fail with distinct `docs-agent.completion-contract.*` diagnostics.
156+
For every maintenance outcome, `source_delta` must be non-empty and caller-bounded: each item has a unique ID and non-empty source refs, and those records are copied canonically into the report. Caller-known drift marked `requires_documentation_change: true` requires an actual Markdown or MDX diff. Bootstrap uses `inventory` with its required positive bootstrap contract and deterministic substantive filesystem checks. Model final prose is never parsed or used for completion.
157157

158-
The untrusted report originates in the native canonical transcript, not as a target-repository file, so honest no-change runs remain clean and do not trigger publication. Only after semantic validation does the validator write canonical report bytes under the excluded `.codebox` artifact root. The command artifact declaration lets WP Codebox expose those validated bytes to reviewers; a runtime declaration or private transcript alone never satisfies semantic completion.
158+
The validator writes canonical report bytes under the excluded `.codebox` artifact root, so honest no-change runs remain clean and do not trigger publication. The command artifact declaration lets WP Codebox expose those deterministic bytes to reviewers; a runtime declaration or private transcript alone never satisfies semantic completion.
159159

160160
## Pull Request Behavior
161161

162162
Docs Agent opens or updates one canonical PR for the configured branch.
163163

164-
- If the selected maintenance surface is current, the run succeeds only with a non-empty caller-bounded source delta, complete evidence-backed coverage, and no workspace diff.
164+
- If the selected maintenance surface is current, the run succeeds only with a non-empty caller-bounded source delta and no workspace diff.
165165
- If maintenance is needed, changes are written only under `writable_paths`.
166166
- If the canonical PR is already open, later runs reuse the same `docs_branch` and PR instead of creating duplicates.
167167
- `validation_dependencies` is an optional caller-owned reusable-workflow input. It is passed through the portable recipe and runs before verification commands when a live runner execution needs setup.
168-
- `job_status`, `transcript_summary`, `credential_mode`, `success_requires_pr`, `validation_dependencies`, and bounded `projected_outputs_json` are exposed as reusable workflow outputs. A `run_agent: false` call returns `job_status: skipped`; a `dry_run: true` call validates without starting a model run. `OPENAI_API_KEY` is only required for a live OpenAI run and is never included in recipes, workflow outputs, or artifacts. Bootstrap lanes require a published pull request and its projected URL for success. Maintenance lanes allow a bounded evidence-backed no-change result by default; set `require_pr: true` when an acceptance or remediation run must fail without a valid target-repository PR. Runtime typed artifact declarations remain optional, while the completion post-command artifact is mandatory and exposed through WP Codebox declared-artifact staging. Raw engine data is not exposed as a workflow output or uploaded reviewer artifact.
168+
- `job_status`, `transcript_summary`, `credential_mode`, `success_requires_pr`, `validation_dependencies`, and bounded `projected_outputs_json` are exposed as reusable workflow outputs. A `run_agent: false` call returns `job_status: skipped`; a `dry_run: true` call validates without starting a model run. `OPENAI_API_KEY` is only required for a live OpenAI run and is never included in recipes, workflow outputs, or artifacts. Bootstrap lanes require a published pull request and its projected URL for success. Maintenance lanes allow a bounded no-change result by default; set `require_pr: true` when an acceptance or remediation run must fail without a valid target-repository PR. Runtime typed artifact declarations remain optional, while the completion post-command artifact is mandatory and exposed through WP Codebox declared-artifact staging. Raw engine data is not exposed as a workflow output or uploaded reviewer artifact.
169169

170170
## Quality Bar
171171

0 commit comments

Comments
 (0)