docs(sync-docs): backfill governance R3/R4b/R4c/R7/R9 across security docs#256
docs(sync-docs): backfill governance R3/R4b/R4c/R7/R9 across security docs#256naveen-kurra wants to merge 1 commit into
Conversation
… docs /sync-docs pass triggered by R4c defer landing on this branch. The governance events / config blocks / hook layer had accumulated a doc debt across four PRs — the R3/R7/R4b/R9 features already merged but never made it into audit-logging.md, policy-decisions.md, the forge.yaml schema, or the .claude skill. Bringing everything current in one pass so the docs match #248's post-merge shape. - docs/security/policy-decisions.md: `step_up` and `defer` rows said "Reserved — not yet emitted". Updated to name the config block that triggers them and cross-link to step-up-auth.md and defer-decisions.md. - docs/security/audit-logging.md: added rows for the nine governance audit event types — intent_alignment, intent_drift, auth_step_up_required, task_deferred, task_deferred_decision, task_deferred_timeout, credential_issued, credential_revoked, credential_failed. Each row lists the fields wire shape and cross-links to the feature doc. Explicitly notes what payloads are NOT allowed to carry (LLM prompts, tool args, credential material). - docs/reference/forge-yaml-schema.md: `security:` section only documented `policy_path`. Extended to cover intent_alignment, intent_drift, step_up, defer with an example yaml block per feature and a field-notes table. Called out the *float64 pointer semantics for thresholds (explicit 0 preserved) and the monotone_n ≤ window rejection. - docs/core-concepts/hooks.md: new "Governance hooks" subsection in the hook reference — one table row per governance hook (R3 / R7 / R4b / R4c / R9) with hook point, config block, and fail behavior. Documents the registration order (guardrails first, then governance, R3 → R4b → R4c → R9). - .claude/skills/forge.md: added rows in §17 Audit event reference for all nine governance events, and a new §12.11 "Governance framework R1–R9" subsection under Security model with the compliance matrix, the where-it-lives pointer, and a cross-link to the compliance-suite live-verification harness. ToC stays H2-only so no ToC edit needed. The .claude/skills/forge-skill-builder.md constant tie-in is untouched — no changes to skill_builder_context.go on this branch.
initializ-mk
left a comment
There was a problem hiding this comment.
Request changes — excellent, comprehensive sync: I cross-checked all six governance PRs (R3/R7/R4b/R4c/R9 plus R5/R6) against the diff and every event, config block, and field matches the shipped code. Two reader-facing defects to fix before merge, plus a couple of minor accuracy/completeness items.
Coverage — all six are covered
| PR | Covered by |
|---|---|
| #245 R3 | intent_alignment event + yaml block (with the *float64 / -1 warn-only semantics) + hooks row + matrix — complete |
| #246 R7 | intent_drift event + yaml block (monotone_n ≤ window, *float64) + hooks row + matrix — complete |
| #247 R4b | auth_step_up_required event + policy-decisions row + yaml block + hooks row + matrix (RequiredError propagation noted) — complete |
| #248 R4c | 3 task_deferred* events + policy-decisions row + yaml block + hooks row + transport/race notes + matrix — complete |
| #236 R9 | 3 credential events + hooks row + matrix; credentials: noted as top-level |
| #237 R5/R6 | dedicated audit-signing.md / audit-tamper-evidence.md already in main; R5/R6 matrix rows + the prev_hash/kid/sigp/sig signing note in the skills doc |
Nothing is missing.
Fix before merge
-
Broken cross-link.
forge-yaml-schema.mdlinksintent-alignment.md#drift-tracking, but the heading is## Drift tracking (governance R7 / #214), whose GitHub anchor is#drift-tracking-governance-r7-214. The link won't resolve — and the PR's own test plan calls for verifying cross-links. Point it at the correct anchor (or drop the fragment). -
Misleading config value. The skills-doc rollout line reads
hard_threshold: 0.85 for the deny tier. That contradicts the0.3default and the calibration guidance inintent-alignment.md— aligned actions land around 0.48–0.8 depending on the embedder, sohard_threshold: 0.85would deny nearly all legitimate traffic. An operator copying it would misconfigure. Use a low value (near the0.3default) or phrase it as "a bit below the observed floor of your normal traffic."
Minor (accuracy / completeness)
-
R9 is not a hook. hooks.md lists JIT credentials as "Wraps
BeforeToolExec(issue) +AfterToolExec(revoke)" and audit-logging.md sayscredential_issuedis "Emitted perBeforeToolExec." It's actually in-tool injection: the injector is wired ontocli_execute/http_request(WithCredentialInjector), which callMaterializeinsideExecuteand revoke via a deferredClose— not a registered entry in the hook chain. Reword so a reader doesn't go looking for a hook that isn't there (e.g. "injected in-tool at Execute; not aBeforeToolExec/AfterToolExechook"). -
Parity gaps (fine to defer):
- The
credentials:(R9) block isn't in the yaml-schema reference — the other four governance blocks got full example blocks; R9 only got a prose pointer. A shortcredentials:example there would match. - audit-logging.md's event reference doesn't note that signed events carry
prev_hash/kid/sigp/sig— the skills doc does. A one-line pointer toaudit-signing.mdin the event reference would keep the two consistent.
- The
Great work overall — the wire-shape and field-level detail is accurate against the code, and the R1–R9 matrix is a genuinely useful single-screen reference. Fix the link + the 0.85 value and I'm happy to approve.
naveen-kurra
left a comment
There was a problem hiding this comment.
Review — 4 findings, docs-only
Docs-only PR (+111/-4 across 5 files) backfilling governance R3/R4b/R4c/R7/R9 across audit-logging.md, policy-decisions.md, forge-yaml-schema.md, hooks.md, and .claude/skills/forge.md. Read the diff line-by-line, cross-checked every factual claim against the code, and verified the cross-links resolve. Four issues surfaced — one operator-facing (would break agents if followed literally), three lower-severity.
Ranked most severe first:
1. .claude/skills/forge.md:791 — rollout guidance's hard_threshold: 0.85 would deny almost every tool call
Rollout: turn each on independently, warn-only first (`hard_threshold: -1`
for R3, `hard_threshold: 0.85` for the deny tier), gather the distribution
against your embedder + workload, then tune.
hard_threshold is "score below → deny." Real aligned actions on OpenAI text-embedding-3-small cluster at 0.4–0.9 (per docs/security/intent-alignment.md's own guidance: "a normal working session clusters at 0.6–0.9"), so setting it to 0.85 denies effectively all traffic. An operator who reads this and follows it literally has an agent that refuses every tool call in production.
Suggested fix: match the sibling doc — "warn-only stage → hard_threshold: -1; then move to hard_threshold a bit below the observed floor of normal traffic (typically 0.2–0.3)."
2. .claude/skills/forge.md:1125 — prev_hash is not gated on the signing key
Signing / hash-chaining adds `prev_hash`, `kid`, `sigp: "jcs-1"`, `sig`
when `FORGE_AUDIT_SIGNING_KEY_B64` is set (R5+R6 / #212+#213).
prev_hash is emitted unconditionally on every event since R5 (#212). Only kid / sigp / sig require the signing key. Confirmed by reading forge-core/runtime/audit.go line 744: event.PrevHash = a.lastHash runs in the emit path independent of any signing key check. An audit consumer reading this doc could conclude that unsigned deployments have no chain protection, which is wrong.
Suggested fix: split the sentence — "Hash-chaining stamps prev_hash on every event (R5 / #212). When FORGE_AUDIT_SIGNING_KEY_B64 is set, signing additionally adds kid, sigp: "jcs-1", and sig (R6 / #213)."
3. docs/reference/forge-yaml-schema.md:~340 — broken anchor #drift-tracking
# R7 (#214) — see docs/security/intent-alignment.md#drift-trackingThe actual heading in intent-alignment.md is ## Drift tracking (governance R7 / #214), which GitHub-flavored-markdown slugifies to #drift-tracking-governance-r7--214. The bare #drift-tracking anchor won't resolve — clicking it lands the reader at the top of the file instead of the drift section.
Suggested fix: docs/security/intent-alignment.md#drift-tracking-governance-r7--214 (or rename the heading to a shorter one and keep the anchor stable).
4. docs/core-concepts/hooks.md:~124 — section heading omits R7
## Governance hooks (R3 / R4b / R4c / R9)
But the table right below has a dedicated row for R7 Intent drift. A reader scanning the doc for "which R covers drift?" doesn't find R7 in the heading. Rename to ## Governance hooks (R3 / R7 / R4b / R4c / R9) (or R3–R9) so the heading and table agree.
Nothing security-critical, no factual claims about R4a/R4b/R4c/R5/R6/R7/R9 mechanics are wrong. The event catalog additions in audit-logging.md and .claude/skills/forge.md § 17 checked out against the code (AuditIntentAlignment, AuditIntentDrift, AuditAuthStepUpRequired, AuditTaskDeferred*, AuditCredential* all match the constants in forge-core/runtime/audit.go). The security: block example yaml in forge-yaml-schema.md matches the pointer-based schema in forge-core/types/config.go. Cross-links to intent-alignment.md, step-up-auth.md, defer-decisions.md, audit-signing.md, audit-tamper-evidence.md, least-privilege-credentials.md, policy-decisions.md all resolve.
Summary
/sync-docs pass triggered by R4c defer landing (#248). The governance events / config blocks / hook layer had accumulated a doc debt across four merged PRs — R3 (#245), R7 (#246), R4b (#247), R9 (#236), and R4c (#248) all shipped code but never made it into
audit-logging.md,policy-decisions.md, theforge.yamlschema reference, or the.claude/skills/forge.mdknowledge doc. Bringing everything current in one pass so the docs match the post-#248 shape ofmain.Files changed
docs/security/policy-decisions.mdstep_upanddeferrows said "Reserved — not yet emitted". Updated to name the config block that triggers each and cross-link to the feature docs.docs/security/audit-logging.mdintent_alignment,intent_drift,auth_step_up_required,task_deferred,task_deferred_decision,task_deferred_timeout,credential_issued,credential_revoked,credential_failed. Each row lists the wire-shape fields, cross-links to the feature doc, and calls out what payloads are NOT allowed to carry (LLM prompts, tool args, credential material).docs/reference/forge-yaml-schema.mdsecurity:section only documentedpolicy_path. Extended to coverintent_alignment,intent_drift,step_up,deferwith an example yaml block per feature and a field-notes table. Explicit callout on the*float64pointer semantics for thresholds (explicit0preserved) and themonotone_n ≤ windowstartup check.docs/core-concepts/hooks.mdBeforeToolExecetc.), fail behavior, cross-link. Documents registration order (guardrails first, then governance R3 → R4b → R4c → R9)..claude/skills/forge.mdTest plan
grep -rn '\[.*\](.*\.md)' README.md docs/— spot-check all cross-links resolve for the added references (intent-alignment.md,step-up-auth.md,defer-decisions.md,least-privilege-credentials.md,audit-signing.md,audit-tamper-evidence.md,policy-decisions.md). Pre-existing broken links underdocs/auth/providers/*.mdare NOT touched by this PR.audit-logging.mdevent table stays readable at the new width;forge-yaml-schema.mdsecurity:example yaml renders with the correct nesting..claude/skills/forge.md§ 12.11 renders as a subsection under § 12 Security model, ahead of § 12.10 Platform admission hook.Not included
.claude/skills/forge-skill-builder.mdbyte-identical-mirror constant is unrelated to this branch; skill_builder_context.go was not touched.docs/auth/providers/(pre-existing, unrelated to governance) — left for a separate cleanup.