feat(ingest): attach a same-type, same-key candidate to the existing concept instead of forking it - #1283
Merged
Conversation
Two OpenSpec changes for deliverables 1 and 2 of the "Quiet Engine" arc: ingest attaches a same-type, same-key candidate to the existing concept instead of writing a -N copy (Event and Person excluded), and deprecation follows the provenance of a superseded Source with a clean forget path. Refs #1268 Refs #1259 Refs #1263
Merge output is unchanged byte for byte (goldens). Refs #1268
…/-N identity rule keyed_documents and canonical_family_member are shared by the HIGH Identity tier, merge and (next) ingest attach. Refs #1268
Event and Person are excluded; a deprecated concept is never a target; a source that already owns a match stays the byte-untouched no-op. Refs #1268
Attach targets join the drift guard instead of the create-only set, are read after extraction, and the commit message names revisions separately. Existing slug-collision tests move to Person, an attach-excluded type. Refs #1268
…y and batch The attach key also lands in the example workspace config, and two existing tests that relied on a same-title fork keep it through the kill switch or distinct titles. Refs #1268
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Deliverable 1 of "The Quiet Engine" arc (#1268): attach, don't fork, at ingest. When an extracted candidate matches an existing concept on the same OKF type and the same normalized title key, ingest revises that concept instead of writing
<slug>-N. This removes the-Nduplicate families at the source rather than queueing them for review.This PR also carries the OpenSpec proposals for deliverables 1 and 2 (
openspec/changes/attach-at-ingest/andopenspec/changes/retire-superseded-sources/) with the owner's decisions recorded. Onlyattach-at-ingestis implemented here;retire-superseded-sources(#1259, #1263) follows separately.Behavior
(type, normalize_key(title))among non-deprecated concepts before the slug-collision path. A match becomes an attach plan; no match keeps today's behavior.## Relatedbullet and bumpsversionby 1. Id, title, description and type never change. It is the first place the engine bumpsversion.attach_at_ingestconfig key, default on for every path including the daemon's inbox watch, with a kill switch (false).**Attach**log entry and no second index bullet.ingested (revised 1 existing object)).docs/cli.mdupdated.Reuse, not duplication
build_merged_document's field-union core is factored out and shared by the newbuild_attached_document; byte-exact merge goldens were committed before the refactor and pass unchanged.-Nidentity rule (bug: merge keeps the disambiguated -N slug as survivor and deletes the canonical slug #1228) are promoted to public functions (keyed_documents,canonical_family_member) instead of re-implemented.Spec deviation from the proposal (applied to the delta spec): the existing-concept lookup is a lazy, memoised
find/readpair read after extraction, not a precomputed mapping, to keep the read close to the commit phase.Existing tests changed: six slug-collision tests in
test_ingest_behaviour.pynow use Person (an attach-excluded type) so they still pin the fork path; thebatch_autocharacterization golden setsattach_at_ingest: falseto keep pinning the fork stream;test_candidate_edges_e2e's fake keys extraction on source text;examples/good-life-demo/openkos.yamlgains the template comment.Size: one PR by the maintainer's choice; about 2,100 lines of implementation and tests plus about 1,900 lines of OpenSpec proposals.
Related issue
Refs #1268
Refs #1259
Type of change
feat— new featurefix— bug fixdocs— documentation onlyrefactor— no behavior changetest— tests onlychore/ci— tooling, build, or CIIngest now revises an existing same-type, same-key concept instead of writing
<slug>-Nby default; setattach_at_ingest: falseto keep the previous behavior.How was this tested?
build_attached_document, 9 for the config key, 5 for the service, 3 for CLI output). The merge goldens passed against the unrefactored code first, so the refactor has a byte-exact oracle.-Ncopies.version+ 1 (7), guarded-target registration (1).ruff check,ruff format --check,mypy .(524 files),evals/run_self_tests.py, andpytest --cov(9582 passed, 2 skipped, 96.47%) pass.Checklist
ruff,mypy,pytest).