feat(harness): agentic-first context & harness-integrity system - #30539
feat(harness): agentic-first context & harness-integrity system#30539TeddyCr wants to merge 35 commits into
Conversation
…ble-Design-System
…f truth Move the 6 real SKILL.md dirs out of .claude/skills/ into skills/ and replace them with relative ../../skills/<name> symlinks matching the existing 12. Merge the diverged .claude and .agents copies of java-checkstyle and ui-checkstyle into one source each, fixing: - py_format is ruff, not black/isort/pycln (per ingestion/Makefile) - ui-checkstyle is one checkstyle job with six gated steps, not three per-area jobs (per .github/workflows/ui-checkstyle.yml) Add the missing pr-checklist and openmetadata-workflow symlinks. Point .agents/skills/ at the same source via symlinks. Location/duplication only; no skill substance changed except the two checkstyle merges. Details in docs/harness-audit/03-consolidation.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reduce always-loaded CLAUDE.md from 591 to 136 lines. Move path- and language-specific guidance into .claude/rules/*.md (paths: frontmatter, loaded only when Claude reads matching files); point procedural sections at existing skills instead of duplicating them. Correct five stale claims against the code, each noted in-file with its audit finding: Webpack->Vite, Python 3.10-3.11->>=3.10 (CI 3.10), 17->19 locale files, 'make generate' is root-only, and UI Checkstyle is one job with six steps (not three jobs). Full old->new line mapping in docs/harness-audit/01-decomposition.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rs, repo-wide format/license .claude/settings.json: replace the 12 advisory/inert hooks with 3 PreToolUse blockers — keep --no-verify; add generated-output protection (block edits to committed/build generated trees, directing to the schema + make generate); add .github/workflows/** edit protection (user authorizes via CLAUDE_ALLOW_WORKFLOW_EDITS=1; the agent cannot self-authorize). Deleted advisory hooks' guidance already lives in .claude/rules/*. Format/license enforced repo-wide via .pre-commit-config.yaml for all contributors: add ui-prettier + ui-license-header local hooks (Java and Python format were already present). Java/Python license deferred (two licenses in-repo + many headerless files). Activate with 'make install_test precommit_install' (added to CLAUDE.md bootstrap). Rationale + trigger/non-trigger test evidence in docs/harness-audit/04-enforcement.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/quality
Committing the read-only audit deliverables and the actionable docs derived
from them:
- docs/harness-audit/{00-findings, 07-settings-scope, 08a-topology,
08b-adherence, 08c-feedback-loops, 08d-hazards, 08e-promotion-list}.md
- docs/{tech-debt, golden-principles, quality}.md
golden-principles.md and 08e-promotion-list.md are drafts for human
ratification — the promotion list changes what blocks contributors' PRs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ons) The harness-audit reports are working artifacts that won't ship, so the path-scoped rules loaded into agent context must not link to them. Removed the (Audit: docs/harness-audit/...) citations from component-library, i18n, migrations, and schema-first; the underlying facts stay stated in place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Untrack the harness-audit working documents (00-findings through 08e-promotion-list, plus 01-decomposition / 03-consolidation / 04-enforcement) — scaffolding, not shipping docs. Files remain on disk (untracked). The derived docs that stay (docs/tech-debt.md, golden-principles.md, quality.md) are untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ARCHITECTURE.md — bird's-eye view (API-request / ingestion-run / search-query paths), a codemap of the 12 Maven modules + the ingestion tree, and the 5 invariants the code actually keeps (acyclic modules, connector ServiceSpec contract, generated-is-a-sink, schema-first, migration append-only) with what enforces each. Every claim traces to the module graph or a file path; the connector-contract and schema-count figures were re-measured (94/95 = 98.9%, 904 schemas). CLAUDE.md gains one pointer line: ARCHITECTURE.md (system map) vs DEVELOPER.md (how-to). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reports) tech-debt.md, golden-principles.md, quality.md no longer cite the working harness-audit reports (which are untracked); the measured numbers and the reproducing commands stay inline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eference) Two generators under scripts/, each with a make target and gated as generated output: - scripts/generate_entity_index.py -> docs/generated/entity-index.md 81 first-class entities (schema + javaType/id discriminator), joined to their generated Java/Python/TS paths and REST resource class (EntityResource<T,R>). - scripts/generate_api_reference.py -> docs/generated/api-reference.md 1748 endpoints parsed from the 122 JAX-RS *Resource.java classes (method + path exact; purpose from @operation(summary) where present, never inferred). Source is the annotations, NOT openapi.yml (a 300-byte SwaggerBundle config stub). Output is byte-identical across runs and hash seeds (sorted, no timestamps), so the freshness CI job can fail on any drift. make targets: generate-entity-index, generate-api-reference, generate-reference-docs. Both outputs are added to the generated-output PreToolUse block in .claude/settings.json. A third generator (db-schema) was intentionally NOT built: it cannot be produced reliably from bootstrap/sql/schema/*.sql without adding a SQL parser + a migration-replay engine + cross-dialect diffing. A reference wrong part of the time is worse than none. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Indexes every knowledge doc under docs/ plus the reference docs that live in
other trees (openmetadata-ui/.../docs/{colors,formutils}.md, the Playwright
coverage docs, ingestion/docs/design/ingestion-diagnostics.md,
bootstrap/MIGRATION_SYSTEM.md). Each entry: path, one-line purpose, when an agent
should read it, git last-modified date, and a freshness verdict
(CURRENT/STALE/SUPERSEDED) verified against the working tree — one plan is
SUPERSEDED, several are CURRENT-with-caveat (footnoted). Moves nothing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
scripts/harness/check_harness.py runs six decay checks and emits GitHub warning
annotations (exit 0 unless --strict, so it never blocks a PR):
1. dead references — a path/make target/yarn script/mvn goal named in CLAUDE.md,
AGENTS.md, ARCHITECTURE.md, docs/index.md, .claude/rules/**, or a SKILL.md that
no longer resolves (parses code spans only; anchored to real repo roots)
2. AGENTS.md drift from CLAUDE.md's corrected stack facts
3. skill symlink integrity (.claude/skills, .agents/skills) + same-name divergence
4. doc-size budgets: CLAUDE.md <=200, ARCHITECTURE.md <=300, each rule <=100
5. rule-glob: a .claude/rules paths: glob matching zero files
6. docs/generated/** freshness (subsumes the reference-docs freshness check)
Runs via python3 scripts/harness/check_harness.py
::warning file=AGENTS.md,line=12::[agents-sync] AGENTS.md says 'Webpack'; the UI is built with Vite (mirror CLAUDE.md's 'Stack at a glance').
::warning file=.claude/rules/java.md,line=1::[doc-size] 144 lines exceeds rule budget of 100
=== harness-integrity summary ===
agents-sync (1):
AGENTS.md:12 AGENTS.md says 'Webpack'; the UI is built with Vite (mirror CLAUDE.md's 'Stack at a glance').
doc-size (1):
.claude/rules/java.md:1 144 lines exceeds rule budget of 100
total: 2 warning(s) locally and a single new root workflow (staged
separately; the workflow-edit guard blocks the agent from writing .github/workflows/).
NOT folded into skills/.github/workflows/lint-standards.yml — that is the skills
plugin's own CI (triggers on skills/**, not run by the monorepo) and can't reach
repo-root files. On the current tree it reports 2 genuine findings (AGENTS.md's
'Webpack', java.md at 144 lines) and zero false positives.
Also: ARCHITECTURE.md ingestion codemap rows now use the file's own '…' abbreviation
convention (they were abbreviated paths written as if literal); CLAUDE.md gains a
pointer-index note describing the checks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AGENTS.md is now generated from CLAUDE.md by scripts/harness/sync_agents_md.py, so the two can no longer drift (this fixes AGENTS.md's Webpack/AntDesign/Flyway contradictions — tech-debt open-metadata#6). Mechanism: - scripts/harness/sync_agents_md.py renders AGENTS.md = banner + CLAUDE.md body - make sync-agents-md regenerates it - harness-integrity check 2 now warns unless AGENTS.md == render(CLAUDE.md) (replaces the earlier Webpack-only drift heuristic) - .claude/settings.json blocks hand-edits to AGENTS.md and redirects to CLAUDE.md - CLAUDE.md pointer-index note updated to describe the sync Harness check on the current tree: 1 warning (java.md 144 > 100 budget); AGENTS.md sync now passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AGENTS.md is now a symlink to CLAUDE.md, so the two are literally the same file and
can never drift. Simpler than the generated mirror it replaces:
- deleted scripts/harness/sync_agents_md.py and the make sync-agents-md target
- harness-integrity check 2 now warns unless AGENTS.md is a symlink resolving to
CLAUDE.md (ln -sf CLAUDE.md AGENTS.md)
- .claude/settings.json block + CLAUDE.md note updated for the symlink mechanism
Harness check: 1 warning (java.md 144 > 100 budget); AGENTS symlink check passes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Runs scripts/harness/check_harness.py on PRs touching the agent-facing config (CLAUDE.md, AGENTS.md, ARCHITECTURE.md, docs/**, .claude/rules/**, skills, Makefile, generator sources). Emits GitHub warning annotations only; never fails a PR. Placed with explicit user authorization for this one file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The GoF patterns this codebase uses idiomatically, each with the canonical class to copy the idiom from - so agents extend the established pattern instead of inventing a parallel one. Grounded entirely in this repo (verified class/package citations), covering Java (Template Method in EntityRepository, Factory/Registry via Entity + SecretsManagerFactory, Strategy, Adapter in SearchClient, Facade in CollectionDAO, Observer, Chain of Responsibility, Command, Visitor via ANTLR, cursor Iterator, Proxy/Composite), Python ingestion (create() contract, ServiceSpec factory, dispatch registries, entity adapters, singledispatch Strategy, generator Iterator, Source->Sink pipeline), and the TS *ClassBase singleton seam. Wired: added to the harness dead-reference check (REF_DOCS) so its ~40 code citations stay verified; pointer added to CLAUDE.md's index (mirrored to AGENTS.md via symlink). Harness check: 1 warning (java.md size); all citations resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLAUDE.md's header now instructs agents to consult docs/index.md (the knowledge index) before writing new docs, so its 27 catalogued design/plan/reference docs are reachable from the always-loaded entry point. Previously docs/index.md was only named inside the dead-reference check's file list, not as a 'read this' pointer. Mirrored to AGENTS.md via the symlink. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
'before writing new ones' was too narrow — docs/index.md is most useful during ordinary coding (find the RDF / migration / auto-classification doc for the area you touch), not only when authoring new docs. Reworded to 'for whatever area you're working on'. Mirrored to AGENTS.md via symlink. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ble-Design-System
…stem' into MINOR-Machine-Readable-Design-System
…ble-Design-System
…stem' into MINOR-Agentic-First-System
The gradient variant's border was migrated from the arbitrary hex border-[#EFF8FF] to the tw:border-brand-50 token utility (#EFF8FF == brand-50); assert the token class instead of the old arbitrary hex. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…stem' into MINOR-Agentic-First-System
Code Review 👍 Approved with suggestions 0 resolved / 3 findingsIntroduces an agentic-first context and harness-integrity system to structure agent guidance and validate documentation freshness. Consider addressing minor findings regarding unclosed file handles in check_harness.py, working tree mutation during generation checks, and silent failures in the freshness check. 💡 Bug: generated-fresh check silently passes if a generator fails📄 scripts/harness/check_harness.py:440-453 check_generated_fresh runs each generator with subprocess.run(..., check=False) and then only inspects Warn when a generator exits non-zero so a crash isn't mistaken for 'fresh'.💡 Quality: harness 'check' mutates the working tree as a side effect📄 scripts/harness/check_harness.py:440-453 check_generated_fresh regenerates docs/generated on every invocation, so running 💡 Quality: Unclosed file handles in check_harness.py helpers📄 scripts/harness/check_harness.py:204-206 📄 scripts/harness/check_harness.py:371 maven_plugin_prefixes() and check_skill_symlinks() open files with bare open(...).read() without a context manager (lines 205 and 371), leaking file descriptors during the tree walk. Use 🤖 Prompt for agentsOptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source |
|



Summary
Restructures the repo's agent-facing context into a layered, self-maintaining system so coding agents (Claude Code, Codex) load the right guidance at the right time — and adds CI that warns when
that guidance drifts from the code. No product/runtime code changes: entirely agent context, docs, tooling, and non-blocking CI.
Motivation
CLAUDE.md had grown into a single ~700-line always-loaded file mixing always-true rules with language/path-specific detail, and nothing caught it drifting from the code. This PR splits
always-loaded guidance from path-scoped rules that auto-load only when you touch a matching file, gives agents a discoverable map of existing docs instead of re-deriving from code, and adds a
warnings-only CI check so dead references / size budgets / broken globs surface on PRs.
What changed
CLAUDE.md → thin map + path-scoped rules — trimmed to a 169-line always-loaded map; nine auto-loading .claude/rules/*.md (java, frontend-react, frontend-styling, component-library, i18n,
frontend-playwright, python-ingestion, schema-first, migrations), each with a paths: glob.
System & knowledge maps — ARCHITECTURE.md (system map + invariants), docs/index.md (doc index with CURRENT/STALE/SUPERSEDED freshness verified against the tree), docs/design-patterns.md (GoF
patterns idiomatic to this repo).
Deterministic reference-doc generators — scripts/generate_entity_index.py → docs/generated/entity-index.md (81 entities); scripts/generate_api_reference.py → docs/generated/api-reference.md
(1748 endpoints from JAX-RS annotations). Byte-identical output; make generate-reference-docs.
Harness-integrity CI (warnings-only) — scripts/harness/check_harness.py (6 checks: dead refs, AGENTS↔CLAUDE sync, skill symlinks, doc-size budgets, rule globs, generated-doc freshness) +
.github/workflows/harness-integrity.yml. Intentionally non-blocking.
AGENTS.md ↔ CLAUDE.md sync — AGENTS.md is now a git symlink to CLAUDE.md (was a drifting 255-line mirror).
Enforcement hooks + skills — .claude/settings.json PreToolUse hooks block edits to generated output/workflows; .pre-commit-config.yaml + scripts/check-ui-*.sh; skills consolidated into a single
skills/ source of truth (symlinked from .claude/skills, .agents/skills).
Repo audit docs — docs/tech-debt.md, docs/quality.md, docs/golden-principles.md (evidence-cited). docs/harness-audit/ left intentionally untracked.
Verification