@datafog/fogclaw 0.2.0 → 0.3.0

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/backlog-tools.d.ts +57 -0
  3. package/dist/backlog-tools.d.ts.map +1 -0
  4. package/dist/backlog-tools.js +173 -0
  5. package/dist/backlog-tools.js.map +1 -0
  6. package/dist/backlog.d.ts +82 -0
  7. package/dist/backlog.d.ts.map +1 -0
  8. package/dist/backlog.js +169 -0
  9. package/dist/backlog.js.map +1 -0
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +6 -0
  12. package/dist/config.js.map +1 -1
  13. package/dist/index.d.ts +2 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +87 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/message-sending-handler.d.ts +2 -1
  18. package/dist/message-sending-handler.d.ts.map +1 -1
  19. package/dist/message-sending-handler.js +5 -1
  20. package/dist/message-sending-handler.js.map +1 -1
  21. package/dist/tool-result-handler.d.ts +2 -1
  22. package/dist/tool-result-handler.d.ts.map +1 -1
  23. package/dist/tool-result-handler.js +5 -1
  24. package/dist/tool-result-handler.js.map +1 -1
  25. package/dist/types.d.ts +15 -0
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/types.js.map +1 -1
  28. package/openclaw.plugin.json +11 -1
  29. package/package.json +7 -1
  30. package/.github/workflows/harness-docs.yml +0 -30
  31. package/AGENTS.md +0 -28
  32. package/docs/DATA.md +0 -28
  33. package/docs/DESIGN.md +0 -17
  34. package/docs/DOMAIN_DOCS.md +0 -30
  35. package/docs/FRONTEND.md +0 -24
  36. package/docs/OBSERVABILITY.md +0 -32
  37. package/docs/PLANS.md +0 -171
  38. package/docs/PRODUCT_SENSE.md +0 -20
  39. package/docs/RELIABILITY.md +0 -60
  40. package/docs/SECURITY.md +0 -52
  41. package/docs/design-docs/core-beliefs.md +0 -17
  42. package/docs/design-docs/index.md +0 -8
  43. package/docs/generated/README.md +0 -36
  44. package/docs/generated/memory.md +0 -1
  45. package/docs/plans/2026-02-16-fogclaw-design.md +0 -172
  46. package/docs/plans/2026-02-16-fogclaw-implementation.md +0 -1606
  47. package/docs/plans/README.md +0 -15
  48. package/docs/plans/active/2026-02-16-feat-openclaw-official-submission-plan.md +0 -386
  49. package/docs/plans/active/2026-02-17-feat-release-fogclaw-via-datafog-package-plan.md +0 -328
  50. package/docs/plans/active/2026-02-17-feat-submit-fogclaw-to-openclaw-plan.md +0 -244
  51. package/docs/plans/active/2026-02-17-feat-tool-result-pii-scanning-plan.md +0 -293
  52. package/docs/plans/tech-debt-tracker.md +0 -42
  53. package/docs/plugins/fogclaw.md +0 -101
  54. package/docs/runbooks/address-review-findings.md +0 -30
  55. package/docs/runbooks/ci-failures.md +0 -46
  56. package/docs/runbooks/code-review.md +0 -34
  57. package/docs/runbooks/merge-change.md +0 -28
  58. package/docs/runbooks/pull-request.md +0 -45
  59. package/docs/runbooks/record-evidence.md +0 -43
  60. package/docs/runbooks/reproduce-bug.md +0 -42
  61. package/docs/runbooks/respond-to-feedback.md +0 -42
  62. package/docs/runbooks/review-findings.md +0 -31
  63. package/docs/runbooks/submit-openclaw-plugin.md +0 -68
  64. package/docs/runbooks/update-agents-md.md +0 -59
  65. package/docs/runbooks/update-domain-docs.md +0 -42
  66. package/docs/runbooks/validate-current-state.md +0 -41
  67. package/docs/runbooks/verify-release.md +0 -69
  68. package/docs/specs/2026-02-16-feat-openclaw-official-submission-spec.md +0 -115
  69. package/docs/specs/2026-02-17-feat-outbound-message-pii-scanning-spec.md +0 -93
  70. package/docs/specs/2026-02-17-feat-submit-fogclaw-to-openclaw.md +0 -125
  71. package/docs/specs/2026-02-17-feat-tool-result-pii-scanning-spec.md +0 -122
  72. package/docs/specs/README.md +0 -5
  73. package/docs/specs/index.md +0 -8
  74. package/docs/spikes/README.md +0 -8
  75. package/fogclaw.config.example.json +0 -33
  76. package/scripts/ci/he-docs-config.json +0 -123
  77. package/scripts/ci/he-docs-drift.sh +0 -112
  78. package/scripts/ci/he-docs-lint.sh +0 -234
  79. package/scripts/ci/he-plans-lint.sh +0 -354
  80. package/scripts/ci/he-runbooks-lint.sh +0 -445
  81. package/scripts/ci/he-specs-lint.sh +0 -258
  82. package/scripts/ci/he-spikes-lint.sh +0 -249
  83. package/scripts/runbooks/select-runbooks.sh +0 -154
  84. package/src/config.ts +0 -183
  85. package/src/engines/gliner.ts +0 -240
  86. package/src/engines/regex.ts +0 -71
  87. package/src/extract.ts +0 -98
  88. package/src/index.ts +0 -381
  89. package/src/message-sending-handler.ts +0 -87
  90. package/src/redactor.ts +0 -51
  91. package/src/scanner.ts +0 -196
  92. package/src/tool-result-handler.ts +0 -133
  93. package/src/types.ts +0 -75
  94. package/tests/config.test.ts +0 -78
  95. package/tests/extract.test.ts +0 -185
  96. package/tests/gliner.test.ts +0 -289
  97. package/tests/message-sending-handler.test.ts +0 -244
  98. package/tests/plugin-smoke.test.ts +0 -250
  99. package/tests/redactor.test.ts +0 -320
  100. package/tests/regex.test.ts +0 -345
  101. package/tests/scanner.test.ts +0 -348
  102. package/tests/tool-result-handler.test.ts +0 -329
  103. package/tsconfig.json +0 -20
@@ -1,125 +0,0 @@
1
- ---
2
- slug: 2026-02-17-feat-submit-fogclaw-to-openclaw
3
- status: intake-complete
4
- date: 2026-02-17T01:56:00Z
5
- owner: sidmohan
6
- plan_mode: execution
7
- spike_recommended: yes
8
- priority: high
9
- ---
10
-
11
- # Submit FogClaw to OpenClaw official plugin channel
12
-
13
- ## Purpose / Big Picture
14
-
15
- FogClaw is already installable and usable via the `@openclaw/fogclaw` package, and it now has repository-side submission readiness artifacts. This initiative is to prepare and execute the **next submission step**: opening and completing the cross-repository contribution in the OpenClaw ecosystem so the plugin can be discovered through official OpenClaw workflows.
16
-
17
- The outcome is observable when a maintainer-facing OpenClaw repo PR is opened with reproducible validation evidence and receives maintainer review status. A user should be able to verify this by checking the new upstream PR and the documented checklist that proves package identity, installability, hook/tool behavior, and testability in a clean environment.
18
-
19
- ## Scope
20
-
21
- ### In Scope
22
-
23
- - Identify the exact official OpenClaw submission path for plugins and prepare the required contribution artifacts for FogClaw.
24
- - Create a maintainer-facing submission PR in the OpenClaw repository using the already-merged `DataFog/fogclaw` release state.
25
- - Include submission evidence mapping between this repository and OpenClaw review expectations (package name/version, manifest, installation command, and reproducible test checks).
26
- - Add/confirm any minimal metadata or docs updates needed specifically for external submission in this repo (if required after upstream validation).
27
- - Track and document outcomes, open questions, and blockers in spec/plan artifacts.
28
-
29
- ### Boundaries
30
-
31
- - No changes to detection logic, redaction strategies, or plugin runtime behavior.
32
- - No implementation changes to OpenClaw platform code.
33
- - No introduction of new dependencies or CI infrastructure in the plugin repo.
34
- - No security/privacy model changes; this effort only covers publication workflow and submission evidence.
35
-
36
- ## Non-Goals
37
-
38
- - Reworking plugin internals or adding new plugin features.
39
- - Re-running full internal feature validation already completed in the plugin merge.
40
- - Creating a parallel package/brand strategy beyond the existing `@openclaw/fogclaw` identity.
41
-
42
- ## Risks
43
-
44
- - OpenClaw may enforce additional fields, naming constraints, or review expectations that were not covered by the DataFog repo readiness work.
45
- - Upstream PR template may require evidence format changes from repo-local PR notes.
46
- - There may be a delay between contribution and maintainer review if expectations remain unclear.
47
- - Maintainers may request a packaging/metadata adjustment after we submit, requiring a follow-up PR.
48
-
49
- ## Rollout
50
-
51
- - Use the already-merged `main` state of `DataFog/fogclaw` as the submission baseline.
52
- - Draft and open the OpenClaw submission PR with reproducible commands and exact expected outputs.
53
- - If OpenClaw maintainers request changes, loop through `respond-to-feedback` and reopen on the same submission branch.
54
- - Close the initiative once the upstream PR is accepted and merged, or route back to `he-implement` if repository changes are required.
55
-
56
- ## Validation and Acceptance Signals
57
-
58
- - Reproducible local evidence command block exists and matches what is sent in the OpenClaw submission PR.
59
- - `@openclaw/fogclaw` package identity remains stable and points to the merged `DataFog/fogclaw` release state.
60
- - OpenClaw upstream PR reaches at least “ready for review” with all requested evidence attachments present.
61
- - The maintainer-facing PR includes explicit answers for submission criteria and known caveats (for example model/download behavior in constrained environments).
62
-
63
- ## Requirements
64
-
65
- | ID | Priority | Requirement |
66
- |---|---|---|
67
- | R1 | high | Prepare a submission PR in the OpenClaw repo that references the `@openclaw/fogclaw` package and the merged DataFog commit history relevant for reviewers.
68
- | R2 | high | Include a clean check list in the OpenClaw PR body with outputs for `npm test`, `npm run build`, `npm run test:plugin-smoke`, and package manifest verification.
69
- | R3 | medium | Confirm any OpenClaw-specific metadata expectations (template fields, review checklist, review labels, or required docs) before requesting maintainer action.
70
- | R4 | medium | Capture and resolve any maintainer feedback by returning to local implementation only when repository edits are required.
71
- | R5 | low | Record submission status and next action in durable docs (`docs/plans/...` and open questions log).
72
-
73
- ## Chosen Direction (Recommended)
74
-
75
- - Use a single upstream pull request targeting the designated OpenClaw repository path as the primary submission vehicle (recommended) because it minimizes fragmentation and matches standard contributor workflows. The risk is that external process details may require iteration.
76
- - A second, duplicate submission route should be avoided unless a maintainer explicitly requests it, because duplicate PRs tend to create conflicting discussions and slower review.
77
-
78
- ## Open Questions
79
-
80
- - **[research]** What exact OpenClaw repository/path and PR template must FogClaw target for official plugin publication?
81
- - **[research]** Does OpenClaw require an additional manifest or catalog file update inside their own repository in addition to package metadata?
82
- - **[decision]** Should this initiative include one follow-up patch branch for any requested metadata changes, or remain submission-only until maintainer asks?
83
- - **[planning]** If additional upstream packaging adjustments are required, should those be merged through the current open submission branch or a fresh follow-up branch?
84
-
85
- ## Success Criteria
86
-
87
- - A new OpenClaw-side PR is created with: plugin identity, install command, reproducible tests, and evidence of `src/index.ts` contract behavior.
88
- - The submission PR body cites the merged plugin-merge commit from `DataFog/fogclaw` as canonical source-of-truth.
89
- - Maintainers can reproduce the core checks from the PR body without guessing or adding setup instructions.
90
- - Any blocking submission questions are answered in the PR thread or captured in plan artifacts before proceeding to final merge.
91
-
92
- ## Constraints
93
-
94
- - Only proceed with outward-facing submission work while preserving plugin behavior unchanged.
95
- - Keep all package names and registry scope aligned to `@openclaw/fogclaw` unless OpenClaw maintainer instruction requires a temporary exception.
96
- - Do not assume access to external OpenClaw maintainer accounts beyond normal GitHub contributor permissions.
97
- - Avoid changing internal plugin code until submission blockers are confirmed as code-level.
98
-
99
- ## Tech Preferences
100
-
101
- - **Language/runtime**: TypeScript / Node.js (repository remains unchanged).
102
- - **Framework/API**: OpenClaw plugin API and GitHub PR process for upstream submission.
103
- - **Infrastructure**: GitHub CLI and repository PR workflow.
104
- - **Rationale**: Keeps this initiative low-risk and focused on process and reviewability rather than implementation.
105
-
106
- ## Handoff
107
-
108
- - This spec should transition to `he-plan` once the exact OpenClaw target path and submission requirements are clear.
109
- - `he-plan` should define submission mechanics and maintainer-proof evidence formatting as separate milestones.
110
- - If significant process uncertainty remains after planning, first route to `he-research` for missing process facts.
111
-
112
- ## Priority
113
-
114
- - priority: high
115
- - rationale: This is the final official publication step and required for wider ecosystem discoverability.
116
-
117
- ## Initial Milestone Candidates
118
-
119
- - M1: Confirm official OpenClaw submission target and required review template/evidence format.
120
- - M2: Draft and open the upstream OpenClaw PR with reproducible checks, package identity, and maintainer-facing rationale.
121
- - M3: Respond to initial feedback loop and either land metadata fixes or close with explicit blocker notes.
122
-
123
- ## Revision Notes
124
-
125
- - 2026-02-17T01:56:00Z: Initialized spec to formalize the cross-repo OpenClaw submission step after plugin readiness merge landed on `DataFog/fogclaw` main.
@@ -1,122 +0,0 @@
1
- ---
2
- slug: 2026-02-17-feat-tool-result-pii-scanning
3
- status: intake-complete
4
- date: 2026-02-17T00:00:00Z
5
- owner: sidmohan
6
- plan_mode: lightweight
7
- spike_recommended: no
8
- priority: high
9
- ---
10
-
11
- # feat: Add PII scanning to tool results via tool_result_persist hook
12
-
13
- ## Purpose / Big Picture
14
-
15
- FogClaw currently only scans the user prompt text (`before_agent_start`). The majority of PII entering an agent's context comes from **tool results** — file reads, web fetches, API calls, database queries. This content bypasses FogClaw entirely today.
16
-
17
- By hooking into OpenClaw's `tool_result_persist` lifecycle, FogClaw can scan and redact PII in tool results **before they are persisted to the session transcript**, closing the largest gap in FogClaw's coverage.
18
-
19
- ## Scope
20
-
21
- ### In Scope
22
-
23
- - Register a `tool_result_persist` hook handler in FogClaw's plugin registration
24
- - Extract text content from `AgentMessage` tool result payloads
25
- - Scan extracted text using the **regex engine only** (synchronous constraint)
26
- - Apply the existing `guardrail_mode`, `entityActions`, `redactStrategy`, and `allowlist` config to detected entities
27
- - Redact PII spans in tool result text content (all modes — redact, block, warn — produce span-level redaction in tool results)
28
- - Emit audit log entries for tool result detections when `auditEnabled: true`
29
- - Add unit tests for the new hook handler
30
- - Add integration test confirming the hook registers and transforms tool results
31
-
32
- ### Boundaries
33
-
34
- - **No GLiNER on this path.** The `tool_result_persist` hook is synchronous-only; async handlers are rejected by OpenClaw. Regex covers structured PII (SSN, email, phone, credit card, IP, date, zip). Unstructured entity detection (person names, organizations) is out of scope for this hook.
35
- - **No `before_tool_call` hook.** This hook exists in OpenClaw's type system but has zero active invocation sites upstream. Will be addressed in a future initiative once OpenClaw wires it in.
36
- - **No `message_sending` hook.** Outbound message scanning is a separate priority.
37
- - **No scanning of `event.messages` history.** Historical message scanning is a separate priority.
38
- - **No new config surface.** Reuse existing FogClaw config — no `toolResultScanning` sub-object.
39
- - **No changes to OpenClaw upstream.** This initiative is FogClaw-only.
40
-
41
- ## Non-Goals
42
-
43
- - Blocking tool execution (requires `before_tool_call`, which is not wired upstream)
44
- - Modifying files on disk
45
- - Scanning binary/image content in tool results
46
- - Real-time GLiNER inference on tool results
47
-
48
- ## Risks
49
-
50
- - **Performance on hot path.** `tool_result_persist` runs synchronously on every tool result. Regex scanning is sub-millisecond for typical payloads, but very large tool results (e.g., reading a 10K-line file) could add measurable latency. Mitigation: benchmark and consider a size cap with configurable threshold.
51
- - **AgentMessage structure varies.** Tool results are typed as `AgentMessage`, whose internal structure depends on the tool and provider. Text extraction must handle multiple content formats without crashing on unexpected shapes. Mitigation: defensive extraction with fallback to no-op.
52
- - **Redaction alters tool output semantics.** Replacing `123-45-6789` with `[SSN_1]` in a tool result changes what the model sees. This is the intended behavior, but could cause unexpected downstream effects if the model tries to use the redacted value literally. Mitigation: this is inherent to the feature and matches existing `before_agent_start` behavior.
53
-
54
- ## Rollout
55
-
56
- - Ship as part of next FogClaw patch release (0.1.7 or 0.2.0)
57
- - Enabled by default when FogClaw is enabled (no separate toggle)
58
- - Audit logging captures tool result scans for observability
59
-
60
- ## Validation and Acceptance Signals
61
-
62
- - Unit tests pass for text extraction from various `AgentMessage` shapes
63
- - Unit tests pass for regex scanning + redaction of tool result content
64
- - Integration test confirms `tool_result_persist` hook registers via `api.on()`
65
- - Integration test confirms a tool result containing PII is transformed before persistence
66
- - Audit log entries are emitted for tool result detections
67
- - Existing `before_agent_start` tests continue to pass (no regression)
68
- - Manual verification: install FogClaw in OpenClaw, have agent read a file with PII, confirm session transcript shows redacted content
69
-
70
- ## Requirements
71
-
72
- | ID | Priority | Requirement |
73
- |---|---|---|
74
- | R1 | critical | Register a `tool_result_persist` hook handler that scans tool result text for PII using the regex engine |
75
- | R2 | critical | Redact detected PII spans in tool result messages using the configured `redactStrategy` (token/mask/hash) |
76
- | R3 | critical | Handler must be synchronous (no Promises returned) — OpenClaw rejects async `tool_result_persist` handlers |
77
- | R4 | high | Apply existing `entityActions` and `guardrail_mode` config to determine per-entity action; all actions produce span-level redaction in tool results |
78
- | R5 | high | Respect existing `allowlist` config (global values, patterns, per-entity lists) |
79
- | R6 | high | Extract text content defensively from `AgentMessage` payloads — handle string content, array-of-content-blocks, and unexpected shapes without throwing |
80
- | R7 | medium | Emit audit log entry per tool result scan when `auditEnabled: true`, including tool name, entity count, and labels (no raw PII values in logs) |
81
- | R8 | medium | Skip scanning for tool results with no extractable text content (binary, empty, non-string) |
82
- | R9 | low | Include `source: "tool_result"` in audit log entries to distinguish from prompt-level scans |
83
-
84
- ## Key Decisions
85
-
86
- - **Regex-only on hot path**: GLiNER is async and cannot run in a synchronous hook. Regex covers the 7 structured PII types (SSN, email, phone, credit card, IP, date, zip) at sub-millisecond latency. This is a deliberate tradeoff — unstructured entities (person names, orgs) are not scanned in tool results.
87
- - **Reuse existing config**: No separate config section for tool result scanning. The same `guardrail_mode`, `entityActions`, `redactStrategy`, and `allowlist` apply everywhere. Simpler mental model for users.
88
- - **Span-level redaction for all modes**: Even when `entityActions` says `block` for an entity type, the tool result is redacted at the span level (not replaced entirely). This preserves non-PII context for the agent while removing sensitive values.
89
-
90
- ## Success Criteria
91
-
92
- - PII in tool results (file reads, web fetches, etc.) is redacted before entering the session transcript
93
- - Regex engine detects SSN, email, phone, credit card, IP, date, and zip in tool result content
94
- - No measurable latency impact for typical tool results (<1KB text)
95
- - Audit log captures tool result scan events with entity counts and labels
96
- - All existing tests pass; new tests cover the hook handler, text extraction, and edge cases
97
-
98
- ## Constraints
99
-
100
- - `tool_result_persist` handler MUST be synchronous (OpenClaw constraint)
101
- - Must not introduce new dependencies
102
- - Must not change the existing `FogClawConfig` type (reuse existing fields)
103
- - Regex engine only — no ONNX/GLiNER on this path
104
-
105
- ## Priority
106
-
107
- - priority: high
108
- - rationale: This closes the single largest gap in FogClaw's PII coverage. Tool results are the primary vector for PII entering agent context, and this hook is the only active interception point OpenClaw provides for that data flow.
109
-
110
- ## Initial Milestone Candidates
111
-
112
- - M1: Text extraction utility — defensively extract text from `AgentMessage` tool result payloads, handling string content, content block arrays, and edge cases. Likely files: `src/extract.ts`, `tests/extract.test.ts`.
113
- - M2: `tool_result_persist` hook handler — register the hook, wire in regex scanning + redaction + audit logging, return transformed message. Likely files: `src/index.ts`, `tests/tool-result-hook.test.ts`.
114
- - M3: Integration smoke test — end-to-end test confirming a registered FogClaw plugin transforms a tool result containing PII. Likely files: `tests/plugin-smoke.test.ts` (extend existing).
115
-
116
- ## Handoff
117
-
118
- After spec approval, proceed to `he-plan` for implementation breakdown. No spike needed — the OpenClaw hook contract is well-documented and the regex engine + redactor already exist in FogClaw.
119
-
120
- ## Revision Notes
121
-
122
- - 2026-02-17T00:00:00Z: Initialized spec from template. Reason: establish intake baseline for tool result PII scanning via `tool_result_persist` hook.
@@ -1,5 +0,0 @@
1
- # Specs
2
-
3
- Store initiative specs here using one file per slug.
4
- Each spec must start with YAML frontmatter and set `plan_mode: lightweight|execution`.
5
- Store spike findings separately in `docs/spikes/`.
@@ -1,8 +0,0 @@
1
- # Specs Index
2
-
3
- Use this index to track initiative specs in `docs/specs/`.
4
-
5
- ## Active Specs
6
-
7
- - `<slug>`: `docs/specs/<slug>-spec.md`
8
-
@@ -1,8 +0,0 @@
1
- # Spikes
2
-
3
- Time-boxed investigations for uncertain/risky initiatives.
4
- Use the pattern `docs/spikes/<slug>-spike.md`.
5
-
6
- Spike docs should start with YAML frontmatter (see `docs/PLANS.md` for the artifact contract).
7
-
8
- Recommended sections: `Context`, `Validation Goal`, `Approach`, `Findings`, `Decisions`, `Recommendation`, `Impact on Upstream Docs`, `Spike Code`, `Remaining Unknowns`, `Time Spent`, and append-only `Revision Notes`.
@@ -1,33 +0,0 @@
1
- {
2
- "enabled": true,
3
- "guardrail_mode": "redact",
4
- "redactStrategy": "token",
5
- "model": "onnx-community/gliner_large-v2.1",
6
- "confidence_threshold": 0.5,
7
- "entityConfidenceThresholds": {
8
- "PERSON": 0.6,
9
- "ORGANIZATION": 0.7
10
- },
11
- "custom_entities": ["project codename", "internal tool name"],
12
- "entityActions": {
13
- "SSN": "block",
14
- "CREDIT_CARD": "block",
15
- "EMAIL": "redact",
16
- "PHONE": "redact",
17
- "PERSON": "warn"
18
- },
19
- "allowlist": {
20
- "values": [
21
- "noreply@example.com"
22
- ],
23
- "patterns": [
24
- "^internal-"
25
- ],
26
- "entities": {
27
- "PERSON": [
28
- "john doe"
29
- ]
30
- }
31
- },
32
- "auditEnabled": true
33
- }
@@ -1,123 +0,0 @@
1
- {
2
- "required_docs": [
3
- "AGENTS.md",
4
- "docs/PLANS.md",
5
- "docs/DOMAIN_DOCS.md"
6
- ],
7
- "expected_runbooks": [
8
- "docs/runbooks/update-agents-md.md",
9
- "docs/runbooks/update-domain-docs.md",
10
- "docs/runbooks/code-review.md",
11
- "docs/runbooks/review-findings.md",
12
- "docs/runbooks/address-review-findings.md",
13
- "docs/runbooks/validate-current-state.md",
14
- "docs/runbooks/reproduce-bug.md",
15
- "docs/runbooks/pull-request.md",
16
- "docs/runbooks/respond-to-feedback.md",
17
- "docs/runbooks/verify-release.md",
18
- "docs/runbooks/record-evidence.md",
19
- "docs/runbooks/ci-failures.md",
20
- "docs/runbooks/merge-change.md"
21
- ],
22
- "domain_docs": [
23
- "docs/DESIGN.md",
24
- "docs/DATA.md",
25
- "docs/FRONTEND.md",
26
- "docs/PRODUCT_SENSE.md",
27
- "docs/RELIABILITY.md",
28
- "docs/SECURITY.md",
29
- "docs/OBSERVABILITY.md",
30
- "docs/design-docs/core-beliefs.md"
31
- ],
32
- "required_headings": {
33
- "docs/SECURITY.md": [
34
- "## Threat Model",
35
- "## Auth Model",
36
- "## Data Sensitivity",
37
- "## Compliance",
38
- "## Controls"
39
- ],
40
- "docs/RELIABILITY.md": [
41
- "## Reliability Goals",
42
- "## Failure Modes",
43
- "## Monitoring",
44
- "## Operational Guardrails"
45
- ],
46
- "docs/FRONTEND.md": [
47
- "## Stack",
48
- "## Conventions",
49
- "## Component Architecture",
50
- "## Performance",
51
- "## Accessibility"
52
- ],
53
- "docs/DESIGN.md": [
54
- "## Design Principles",
55
- "## Visual Direction",
56
- "## Interaction Standards"
57
- ],
58
- "docs/PRODUCT_SENSE.md": [
59
- "## Target Users",
60
- "## Key Outcomes",
61
- "## Decision Heuristics",
62
- "## Quality Criteria"
63
- ],
64
- "docs/DATA.md": [
65
- "## Data Model",
66
- "## Migrations",
67
- "## Backfills And Data Fixes",
68
- "## Integrity And Consistency",
69
- "## Sensitive Data Notes"
70
- ],
71
- "docs/OBSERVABILITY.md": [
72
- "## Logging Strategy",
73
- "## Metrics",
74
- "## Traces",
75
- "## Health Checks",
76
- "## Agent Access"
77
- ]
78
- },
79
- "artifact_placeholder_patterns": [
80
- "<slug>",
81
- "<YYYY-",
82
- "<title>"
83
- ],
84
- "lint_completed_plans": true,
85
- "required_spec_frontmatter_keys": [
86
- "slug",
87
- "status",
88
- "date",
89
- "owner",
90
- "plan_mode",
91
- "spike_recommended",
92
- "priority"
93
- ],
94
- "required_plan_frontmatter_keys": [
95
- "slug",
96
- "status",
97
- "phase",
98
- "plan_mode",
99
- "priority",
100
- "owner"
101
- ],
102
- "required_spike_frontmatter_keys": [
103
- "slug",
104
- "status",
105
- "date",
106
- "owner",
107
- "timebox"
108
- ],
109
- "drift_rules": [
110
- {
111
- "regex": "(^auth/|/auth/|^middleware/|/middleware/|(^|/)security/|(^|/)permissions/)",
112
- "doc": "docs/SECURITY.md"
113
- },
114
- {
115
- "regex": "(^infra/|^ops/|^deploy/|^terraform/|^k8s/|^helm/|(^|/)monitoring/|(^|/)alerts/)",
116
- "doc": "docs/RELIABILITY.md"
117
- },
118
- {
119
- "regex": "(^package\\\\.json$|^pnpm-lock\\\\.yaml$|^yarn\\\\.lock$|^bun\\\\.lockb$|^tsconfig\\\\.json$|^vite\\\\.config\\\\.|^next\\\\.config\\\\.)",
120
- "doc": "docs/FRONTEND.md"
121
- }
122
- ]
123
- }
@@ -1,112 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
-
4
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
- DEFAULT_CONFIG_PATH="scripts/ci/he-docs-config.json"
6
-
7
- config_path="${HARNESS_DOCS_CONFIG:-$DEFAULT_CONFIG_PATH}"
8
- config_file="${REPO_ROOT}/${config_path}"
9
-
10
- if [[ ! -f "$config_file" ]]; then
11
- echo "Error: he-docs-drift missing/invalid config: Missing config '${config_path}'. Fix: create it (bootstrap should do this) or set HARNESS_DOCS_CONFIG." >&2
12
- exit 2
13
- fi
14
-
15
- cfg="$(cat "$config_file")"
16
- if ! echo "$cfg" | jq -e 'type == "object"' >/dev/null 2>&1; then
17
- echo "Error: he-docs-drift missing/invalid config: Config must be a JSON object." >&2
18
- exit 2
19
- fi
20
-
21
- base_ref="${GITHUB_BASE_REF:-}"
22
- head_ref="${GITHUB_HEAD_REF:-}"
23
-
24
- if [[ -n "$base_ref" ]]; then
25
- diff_range="origin/${base_ref}...HEAD"
26
- else
27
- if git -C "$REPO_ROOT" rev-parse -q --verify HEAD~1 >/dev/null 2>&1; then
28
- diff_range="HEAD~1...HEAD"
29
- else
30
- diff_range=""
31
- fi
32
- fi
33
-
34
- echo "he-docs-drift: starting" >&2
35
- echo "Repro: bash scripts/ci/he-docs-drift.sh" >&2
36
- if [[ -n "$base_ref" ]]; then
37
- echo "PR context: base_ref='${base_ref}' head_ref='${head_ref}' diff='${diff_range}'" >&2
38
- else
39
- echo "Local context: diff='${diff_range}'" >&2
40
- fi
41
-
42
- if [[ -n "$diff_range" ]]; then
43
- changed="$(git -C "$REPO_ROOT" diff --name-only "$diff_range" 2>/dev/null || true)"
44
- else
45
- changed="$(git -C "$REPO_ROOT" diff-tree --no-commit-id --name-only -r HEAD 2>/dev/null || true)"
46
- fi
47
-
48
- # Trim empty lines
49
- changed="$(echo "$changed" | sed '/^[[:space:]]*$/d')"
50
-
51
- if [[ -z "$changed" ]]; then
52
- echo "he-docs-drift: no changes detected"
53
- exit 0
54
- fi
55
-
56
- # Build list of changed docs (files starting with docs/)
57
- changed_docs="$(echo "$changed" | grep '^docs/' || true)"
58
-
59
- # Extract drift_rules array; default to empty array if missing or wrong type
60
- drift_rules="$(echo "$cfg" | jq -c '.drift_rules // [] | if type == "array" then . else [] end')"
61
- rule_count="$(echo "$drift_rules" | jq 'length')"
62
-
63
- missing=0
64
-
65
- for ((i = 0; i < rule_count; i++)); do
66
- rule="$(echo "$drift_rules" | jq -c ".[$i]")"
67
-
68
- # Skip non-object entries
69
- if ! echo "$rule" | jq -e 'type == "object"' >/dev/null 2>&1; then
70
- continue
71
- fi
72
-
73
- regex="$(echo "$rule" | jq -r '.regex // empty')"
74
- doc="$(echo "$rule" | jq -r '.doc // empty')"
75
-
76
- if [[ -z "$regex" || -z "$doc" ]]; then
77
- continue
78
- fi
79
-
80
- # Validate regex by testing it
81
- if ! echo "" | grep -qE "$regex" 2>/dev/null && [[ $? -eq 2 ]]; then
82
- echo "Error: invalid drift rule regex: ${regex}" >&2
83
- missing=1
84
- continue
85
- fi
86
-
87
- # Find changed files matching the regex
88
- matching="$(echo "$changed" | grep -E "$regex" || true)"
89
-
90
- if [[ -z "$matching" ]]; then
91
- continue
92
- fi
93
-
94
- # Check if the required doc is in the changed docs list
95
- if ! echo "$changed_docs" | grep -qxF "$doc" 2>/dev/null; then
96
- sample="$(echo "$matching" | head -n 10 | sed 's/^/- /')"
97
- echo "::error file=${doc},title=Docs drift gate::Missing required doc update '${doc}' when files match /${regex}/ (see job logs for matching files)."
98
- echo "Missing doc update: '${doc}' should change when files match /${regex}/." >&2
99
- echo "Matching files (up to 10):" >&2
100
- echo "$sample" >&2
101
- echo "Fix: update '${doc}' in this PR, or edit drift_rules in '${DEFAULT_CONFIG_PATH}' (or HARNESS_DOCS_CONFIG) if this mapping is wrong." >&2
102
- missing=1
103
- fi
104
- done
105
-
106
- if [[ "$missing" -ne 0 ]]; then
107
- echo "Error: docs drift gate failed (see missing doc updates above)" >&2
108
- exit 1
109
- fi
110
-
111
- echo "he-docs-drift: OK"
112
- exit 0