Ask HN: How to deal with shipping AI-written code you don't understand?
As large language models rapidly accelerate software development, many engineers are now shipping code they didn’t write — and often don’t fully understand. Comments span a spectrum from “if the tests pass, ship it” to insisting that releasing opaque AI-generated code is negligent, with proposed mitigations including heavier automated testing, formal verification, strict architectural control, and multi-agent review. Beneath the tooling debate lies a deeper concern: whether this shift is eroding craftsmanship and accountability in software, or simply moving engineers up a level of abstraction toward design and specification.
Testing, verification, and “if it works”
- Many argue that heavy automated testing is the only sane way to ship AI-written code: large unit and integration suites, cross-arch test farms, fuzzing, chaos testing, mutation testing, and e2e tests.
- Some adopt TDD strictly, including for agents: agent writes failing tests first, then code until they pass.
- Others worry that letting the same LLM write both code and tests is dangerous, since they can share blind spots; mitigations include:
- Separate “code” and “test” agents.
- Multiple different LLMs in adversarial review loops.
- Intentionally injecting faults and verifying tests catch them.
- Several insist tests alone are not enough: they don’t verify design, can’t prove absence of vulnerabilities, and AI-written tests are often weak or self-justifying.
Architecture, design, and the human role
- A common pattern: humans design the architecture and abstractions (“skeleton”), LLMs fill in implementations (“flesh”).
- People emphasize up-front planning: feature design docs, implementation plans, architecture diagrams, invariants, and contracts; LLMs then implement within those constraints.
- Some liken this to principal engineer work: you understand intent and structure, not every line.
- Others say if you don’t understand the code, you’re effectively a manager/spec-writer, not an engineer.
Quality, technical debt, and security
- Enthusiasts report major speedups and claim quality can be high with good planning and guardrails.
- Skeptics see “slop” and fear an explosion of tech debt, fragile architectures, and huge future maintenance cost.
- There’s debate over security: some predict “epic” CVEs from unreviewed AI code; others note human-written code is already insecure and argue the root problem is lack of professional standards, not AI per se.
Tools, guardrails, and workflows
- People build guardrail frameworks: static analysis, linters, coverage gates, CVE scanners, performance checks, observability dashboards, staging/feature flags, backups, and automated rollback.
- Some use agent “teams”: builder, reviewer, QA, and a higher-level “CTO”/manager agent coordinating tasks.
- New tools appear for:
- PR summarization and categorization.
- Architecture and call-graph visualization.
- Interactive code exploration and “explainers” for complex subsystems.
- Several now spend less time typing code and more time on testing, design review, and monitoring.
Professional norms and career anxieties
- One camp: “never ship code you don’t understand”; doing so is negligent and debases the profession.
- The other: in large systems you’ve never fully understood all shipped code (dependencies, colleagues’ work), so this is an extension of existing practice.
- Strong undercurrent of anxiety: fear of becoming “meat proxies” for agents, of degraded engineering culture, and of future downgrading of SWE roles vs. PM/“maintenance engineer”.
- Others embrace the shift, arguing that refusing to use AI is career-limiting, and that real leverage now is in design, specification, and building robust processes around agents.
Abstraction level and domain differences
- Many analogize LLM coding to past abstraction jumps (compilers, ORMs, frameworks), but critics respond that LLMs are non-deterministic black boxes unlike compilers.
- Tolerance for AI-written, poorly understood code strongly depends on blast radius:
- More relaxed for UI, internal tools, dashboards, social features.
- Much stricter for payment systems, ledgers, infra, aerospace/medical-like domains.