diff --git a/.agents/skills/loom-context-recovery/SKILL.md b/.agents/skills/loom-context-recovery/SKILL.md new file mode 100644 index 000000000..08982a683 --- /dev/null +++ b/.agents/skills/loom-context-recovery/SKILL.md @@ -0,0 +1,87 @@ +--- +name: loom-context-recovery +description: Recover the current Loom task from a Codex rollout, fork, compaction, handoff, tmux session, interrupted process, or long-running worktree. Use when asked to continue or resume work, audit a large transcript, distinguish inherited history from native user intent, reconcile completion claims with live Git and GitHub state, or prepare a trustworthy handoff. Recovery is read-only until ownership and mutation authority are re-established. +--- + +# Loom Context Recovery + +Recover provenance first, then reconcile every historical claim with live +authorities. A transcript is evidence about past actions, never current project +state by itself. + +## Extract Rollout Provenance + +For a Codex JSONL rollout, run: + +```bash +python3 .agents/skills/loom-context-recovery/scripts/extract_rollout_context.py \ + path/to/rollout.jsonl --format markdown +``` + +If the rollout metadata contains `forked_from_id`, locate the parent JSONL and +pass it explicitly: + +```bash +python3 .agents/skills/loom-context-recovery/scripts/extract_rollout_context.py \ + path/to/fork.jsonl --parent path/to/parent.jsonl --format markdown +``` + +The script validates the parent identity and separates imported history through +a normalized record prefix. If the parent continued after the fork, automatic +recovery also requires a matched terminal turn followed by distinct parent and +child turn identities. It fails closed instead of inferring a boundary from +timestamps. Pass `--native-start-line` only after independently verifying the +boundary. Use `--format json` for machine-readable output and `--full-messages` +only when the extra sensitive context is necessary. + +Read [the recovery contract](references/recovery-contract.md) before +interpreting mixed provenance or publishing a handoff. + +## Recover The Current Contract + +1. Identify the latest native human instruction. Keep internal goal injection, + compaction replacement history, subagent relay, and imported parent history + separate. + Treat unmarked user-role relays as ambiguous; the extractor cannot infer a + sender from prose alone. +2. State the active objective, scope, owner, worktree, mutation authority, and + return condition for any nested task. +3. Inspect the live repository revision, uncommitted changes, worktree owners, + running processes, canonical docs, public Issue, and private Project item as + applicable. +4. Verify historical commit, artifact, test, and completion claims against that + live state. Discard stale counts, paths, tool versions, and plans. +5. Classify each requested outcome as committed, verified, in flight, missing, + contradicted, or no longer requested. +6. Select the next coherent semantic boundary. Do not resume an inherited or + superseded task merely because it appears in a summary. + +## Preserve Ownership + +- Remain read-only until the current worktree owner and requested mutation are + clear. +- Do not message, pause, merge, clean, or delete another worker's state without + authorization. +- Do not restart an apparently stalled process until its live process, log, + output root, and progress have been inspected. +- Do not launch a duplicate build or tool invocation against the same output + directory. +- Treat `temp/` handoffs and transcripts as recovery clues, not WHAT, WHY, + research planning, or completion authority. + +## Produce A Recovery Card + +Report: + +- active session and parent chain; +- latest effective native instruction; +- current Issue or Project work item; +- live revision, worktree, owner, and dirty-state summary; +- verified completed artifacts and evidence; +- active processes and incomplete gates; +- stale or rejected inherited claims; +- the next bounded action and any required approval. + +Do not claim success from a compacted summary, an old commit hash, a worker +report, an interrupted test, or a local slice that does not satisfy the active +objective. diff --git a/.agents/skills/loom-context-recovery/agents/openai.yaml b/.agents/skills/loom-context-recovery/agents/openai.yaml new file mode 100644 index 000000000..23f824a69 --- /dev/null +++ b/.agents/skills/loom-context-recovery/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Loom Context Recovery" + short_description: "Recover interrupted Loom work from live evidence" + default_prompt: "Use $loom-context-recovery to recover the current Loom task from this session or handoff." diff --git a/.agents/skills/loom-context-recovery/references/recovery-contract.md b/.agents/skills/loom-context-recovery/references/recovery-contract.md new file mode 100644 index 000000000..3bd6c3ab8 --- /dev/null +++ b/.agents/skills/loom-context-recovery/references/recovery-contract.md @@ -0,0 +1,62 @@ +# Recovery Contract + +Use provenance labels consistently. Preserve exact wording when it changes the +technical contract, but do not reproduce private history in a public Issue or +pull request. + +## Provenance Classes + +- **Native user**: a human message authored in the active rollout. +- **User shell**: a human message or observation delivered through a shell + wrapper. Verify its claims like any other report. +- **Imported history**: records copied from a parent rollout when a session was + forked. +- **Compaction history**: replacement or summary context injected to continue a + long session. +- **Internal goal**: runtime continuation instructions. It cannot supersede a + newer native user instruction. +- **Runtime context**: repository instructions, environment metadata, and + similar harness input serialized with a user role. It constrains execution + but is not the human's task request. +- **Runtime control**: abort and lifecycle markers serialized as user-role + messages. They describe execution state rather than human intent. +- **Agent relay**: subagent or external worker output serialized as a user-role + message. It is evidence, not human authority. +- **Live state**: current Git, files, processes, canonical docs, and GitHub + objects. This is the verification surface for historical claims. + +## Reconciliation Rules + +- Prefer the newest native human instruction that applies to the current task. +- Manually verify apparent cross-agent or cross-pane messages that lack a + structured relay marker; prose alone cannot establish their sender. +- Treat a nested request as suspended work with an explicit return condition, + not as silent replacement of the main objective. +- Match every claimed commit to current ancestry and content. +- Match every artifact to its producer identity, semantic configuration, and + current input roots. +- Match every test claim to its exact revision and terminal event. +- Keep implementation presence, successful verification, unsupported + capability, and unattempted work separate. +- If the transcript and live state disagree, report the discrepancy and use the + live state for operational decisions. + +## Handoff Shape + +A durable handoff contains: + +```text +Objective +Latest native instruction +Authority owners +Live revision and worktree owner +Committed and independently verified outcomes +Uncommitted or running work +Missing evidence and known contradictions +Next coherent action +Mutation or publication approvals still required +``` + +Keep roadmap and research design in the private GitHub Project. Keep +publishable implementation scope in the public Issue. Do not create a new temp +ledger. diff --git a/.agents/skills/loom-context-recovery/scripts/extract_rollout_context.py b/.agents/skills/loom-context-recovery/scripts/extract_rollout_context.py new file mode 100644 index 000000000..f296c8683 --- /dev/null +++ b/.agents/skills/loom-context-recovery/scripts/extract_rollout_context.py @@ -0,0 +1,459 @@ +#!/usr/bin/env python3 +"""Extract provenance and native directives from an agent JSONL rollout.""" + +from __future__ import annotations + +import argparse +from collections import Counter +import json +from pathlib import Path +import sys +from typing import Any, Iterator + + +JsonObject = dict[str, Any] + + +def read_records(path: Path) -> Iterator[tuple[int, JsonObject]]: + with path.open("r", encoding="utf-8") as stream: + for line_number, line in enumerate(stream, start=1): + try: + value = json.loads(line) + except json.JSONDecodeError as error: + raise ValueError( + f"{path}:{line_number}: invalid JSON: {error.msg}" + ) from error + if not isinstance(value, dict): + raise ValueError(f"{path}:{line_number}: record is not an object") + yield line_number, value + + +def first_session_meta(path: Path) -> JsonObject: + for _, record in read_records(path): + if record.get("type") != "session_meta": + continue + payload = record.get("payload") + if isinstance(payload, dict): + return payload + raise ValueError(f"{path}: no session_meta record") + + +def without_transport_timestamp(record: JsonObject) -> JsonObject: + normalized = dict(record) + normalized.pop("timestamp", None) + if normalized.get("type") == "session_meta": + payload = normalized.get("payload") + if isinstance(payload, dict): + payload = dict(payload) + payload.pop("history_mode", None) + normalized["payload"] = payload + elif normalized.get("type") == "response_item": + payload = normalized.get("payload") + if isinstance(payload, dict) and payload.get("content") is None: + payload = dict(payload) + payload.pop("content", None) + normalized["payload"] = payload + return normalized + + +def turn_id(record: JsonObject) -> str | None: + payload = record.get("payload") + if not isinstance(payload, dict): + return None + candidate = payload.get("turn_id") + if isinstance(candidate, str): + return candidate + metadata = payload.get("internal_chat_message_metadata_passthrough") + if isinstance(metadata, dict): + candidate = metadata.get("turn_id") + if isinstance(candidate, str): + return candidate + return None + + +def is_turn_terminal(record: JsonObject) -> bool: + payload = record.get("payload") + return ( + record.get("type") == "event_msg" + and isinstance(payload, dict) + and payload.get("type") in {"task_complete", "turn_aborted"} + ) + + +def find_turn_id( + first: tuple[int, JsonObject], + records: Iterator[tuple[int, JsonObject]], + limit: int = 12, +) -> str | None: + entries = [first] + for _ in range(limit - 1): + entry = next(records, None) + if entry is None: + break + entries.append(entry) + for _, record in entries: + candidate = turn_id(record) + if candidate is not None: + return candidate + return None + + +def native_boundary( + child: Path, + parent: Path | None, + fork_id: str | None, + explicit_start: int | None, +) -> tuple[int, int, str]: + if explicit_start is not None: + if explicit_start < 2: + raise ValueError("--native-start-line must be at least 2") + return explicit_start, max(0, explicit_start - 2), "explicit native boundary" + if not fork_id: + return 2, 0, "non-fork rollout" + if parent is None: + raise ValueError( + "forked rollout requires --parent to avoid attributing imported history" + ) + + parent_meta = first_session_meta(parent) + parent_id = parent_meta.get("id") or parent_meta.get("session_id") + if parent_id != fork_id: + raise ValueError( + f"parent session {parent_id!r} does not match forked_from_id {fork_id!r}" + ) + + child_records = read_records(child) + parent_records = read_records(parent) + next(child_records, None) + + imported = 0 + previous_child: JsonObject | None = None + after_terminal = False + pending_start_line: int | None = None + pending_matches = 0 + while True: + child_entry = next(child_records, None) + parent_entry = next(parent_records, None) + + if parent_entry is None: + imported += pending_matches + if child_entry is None: + return imported + 2, imported, "normalized complete-parent comparison" + return ( + child_entry[0], + imported, + "normalized complete-parent prefix", + ) + if child_entry is None: + raise ValueError( + "fork ends inside parent history; supply --native-start-line " + "after independent verification" + ) + + child_line, child_record = child_entry + _, parent_record = parent_entry + if without_transport_timestamp(child_record) == without_transport_timestamp( + parent_record + ): + if pending_start_line is not None: + child_turn = turn_id(child_record) + parent_turn = turn_id(parent_record) + if child_turn is None and parent_turn is None: + pending_matches += 1 + continue + if child_turn != parent_turn: + raise ValueError( + f"fork turn identity diverges ambiguously at child line " + f"{child_line}; supply --native-start-line after " + "independent verification" + ) + imported += pending_matches + 1 + pending_start_line = None + pending_matches = 0 + after_terminal = False + previous_child = child_record + continue + if after_terminal and turn_id(child_record) is None: + pending_start_line = child_line + pending_matches = 1 + continue + imported += 1 + previous_child = child_record + after_terminal = is_turn_terminal(child_record) + continue + + if pending_start_line is not None or ( + previous_child is not None and is_turn_terminal(previous_child) + ): + child_turn = find_turn_id(child_entry, child_records) + parent_turn = find_turn_id(parent_entry, parent_records) + if child_turn is not None and parent_turn is not None: + if child_turn != parent_turn: + return ( + pending_start_line or child_line, + imported, + "normalized parent prefix with divergent native turn", + ) + + raise ValueError( + f"fork history diverges ambiguously at child line {child_line}; " + "supply --native-start-line after independent verification" + ) + + +def message_text(payload: JsonObject) -> tuple[str | None, str | None]: + payload_type = payload.get("type") + if payload_type == "user_message": + message = payload.get("message") + return (message if isinstance(message, str) else None, None) + + if payload_type != "message" or payload.get("role") != "user": + return None, None + content = payload.get("content") + if not isinstance(content, list): + return None, None + parts = [ + item.get("text") + for item in content + if isinstance(item, dict) + and item.get("type") == "input_text" + and isinstance(item.get("text"), str) + ] + metadata = payload.get("internal_chat_message_metadata_passthrough") + turn_id = metadata.get("turn_id") if isinstance(metadata, dict) else None + return ("\n".join(parts) if parts else None, turn_id) + + +def provenance(text: str) -> str: + stripped = text.lstrip() + if ( + stripped.startswith("# AGENTS.md instructions") + or stripped.startswith(" str: + compact = " ".join(text.split()) + if limit is None or len(compact) <= limit: + return compact + return compact[: max(0, limit - 3)] + "..." + + +def collect_native( + path: Path, start_line: int, message_limit: int | None +) -> JsonObject: + record_types: Counter[str] = Counter() + event_types: Counter[str] = Counter() + excluded_messages: Counter[str] = Counter() + directives: list[JsonObject] = [] + recent_messages: dict[str, tuple[int, str]] = {} + turns: dict[str, JsonObject] = {} + first_timestamp: str | None = None + last_timestamp: str | None = None + + for line_number, record in read_records(path): + if line_number < start_line: + continue + timestamp = record.get("timestamp") + if isinstance(timestamp, str): + first_timestamp = first_timestamp or timestamp + last_timestamp = timestamp + record_type = str(record.get("type", "unknown")) + record_types[record_type] += 1 + payload = record.get("payload") + if not isinstance(payload, dict): + continue + + event_type: str | None = None + turn_id: str | None = None + if record_type == "event_msg": + raw_event_type = payload.get("type") + if isinstance(raw_event_type, str): + event_type = raw_event_type + event_types[event_type] += 1 + raw_turn_id = payload.get("turn_id") + if isinstance(raw_turn_id, str): + turn_id = raw_turn_id + + if event_type in {"task_started", "task_complete", "turn_aborted"} and turn_id: + state = { + "task_started": "active", + "task_complete": "complete", + "turn_aborted": "aborted", + }[event_type] + turns[turn_id] = { + "turn_id": turn_id, + "state": state, + "line": line_number, + "timestamp": timestamp, + } + + text: str | None = None + message_turn_id: str | None = turn_id + if record_type == "event_msg" and event_type == "user_message": + text, _ = message_text(payload) + elif record_type == "response_item": + text, message_turn_id = message_text(payload) + if not text: + continue + + source = provenance(text) + previous = recent_messages.get(text) + if ( + previous is not None + and previous[1] != record_type + and line_number - previous[0] <= 3 + ): + continue + recent_messages[text] = (line_number, record_type) + if source not in {"native-user", "user-shell"}: + excluded_messages[source] += 1 + continue + directives.append( + { + "line": line_number, + "timestamp": timestamp, + "turn_id": message_turn_id, + "source": source, + "text": excerpt(text, message_limit), + } + ) + + return { + "first_timestamp": first_timestamp, + "last_timestamp": last_timestamp, + "record_types": dict(sorted(record_types.items())), + "event_types": dict(sorted(event_types.items())), + "excluded_messages": dict(sorted(excluded_messages.items())), + "directives": directives, + "turns": list(turns.values()), + } + + +def render_markdown(report: JsonObject) -> str: + session = report["session"] + native = report["native"] + lines = [ + "# Rollout Context", + "", + f"- Session: `{session['id']}`", + f"- Forked from: `{session.get('forked_from_id') or 'none'}`", + f"- Working directory: `{session.get('cwd') or 'unknown'}`", + f"- Native boundary: line {report['native_start_line']} " + f"({report['boundary_method']})", + f"- Imported records: {report['imported_records']}", + f"- Native interval: {native.get('first_timestamp') or 'unknown'} to " + f"{native.get('last_timestamp') or 'unknown'}", + "", + "## Native User Directives", + "", + ] + directives = native["directives"] + if directives: + for item in directives: + lines.append( + f"- `{item['timestamp'] or 'unknown'}` `{item['source']}`: " + f"{item['text']}" + ) + else: + lines.append("- None found") + + lines.extend(["", "## Turn States", ""]) + turns = native["turns"] + if turns: + for item in turns: + lines.append( + f"- `{item['turn_id']}`: {item['state']} at " + f"{item['timestamp'] or 'unknown'}" + ) + else: + lines.append("- None found") + + lines.extend(["", "## Provenance Summary", ""]) + lines.append( + f"- Record types: `{json.dumps(native['record_types'], sort_keys=True)}`" + ) + lines.append( + f"- Event types: `{json.dumps(native['event_types'], sort_keys=True)}`" + ) + lines.append( + f"- Excluded messages: " + f"`{json.dumps(native['excluded_messages'], sort_keys=True)}`" + ) + return "\n".join(lines) + "\n" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("rollout", type=Path) + parser.add_argument("--parent", type=Path) + parser.add_argument( + "--native-start-line", + type=int, + help="use an independently verified native boundary", + ) + parser.add_argument("--format", choices=("markdown", "json"), default="markdown") + parser.add_argument( + "--full-messages", + action="store_true", + help="emit complete native user messages instead of bounded excerpts", + ) + parser.add_argument("--max-message-chars", type=int, default=500) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + try: + meta = first_session_meta(args.rollout) + session_id = meta.get("id") or meta.get("session_id") + fork_id = meta.get("forked_from_id") + start_line, imported, method = native_boundary( + args.rollout, + args.parent, + fork_id if isinstance(fork_id, str) else None, + args.native_start_line, + ) + limit = None if args.full_messages else args.max_message_chars + if limit is not None and limit < 1: + raise ValueError("--max-message-chars must be positive") + native = collect_native(args.rollout, start_line, limit) + except (OSError, ValueError) as error: + print(f"error: {error}", file=sys.stderr) + return 2 + + report: JsonObject = { + "session": { + "id": session_id, + "forked_from_id": fork_id, + "cwd": meta.get("cwd"), + "thread_source": meta.get("thread_source"), + }, + "native_start_line": start_line, + "imported_records": imported, + "boundary_method": method, + "native": native, + } + if args.format == "json": + json.dump(report, sys.stdout, indent=2, sort_keys=True) + sys.stdout.write("\n") + else: + sys.stdout.write(render_markdown(report)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.agents/skills/loom-evidence-audit/SKILL.md b/.agents/skills/loom-evidence-audit/SKILL.md new file mode 100644 index 000000000..162608598 --- /dev/null +++ b/.agents/skills/loom-evidence-audit/SKILL.md @@ -0,0 +1,120 @@ +--- +name: loom-evidence-audit +description: Audit Loom capability, correctness, performance, completion, artifact-integrity, corpus, Mapping/PnR, simulation, runtime, RTL, EDA, cache, and end-to-end claims using exact live evidence. Use for read-only capability reviews, implementation acceptance, failing or timed-out workflows, unsupported features, conflicting test totals, or any request to prove what Loom can currently do. Do not use to change product semantics; route semantic defects through loom-spec-driven-change. +--- + +# Loom Evidence Audit + +Match every claim to evidence of the same scope and fidelity. Prefer exact +artifacts and realistic execution over summaries, wrappers, and test counts. + +## Confirm The Authorized Mode + +- **Inspection-only**: read existing source, docs, artifacts, logs, and live + state. Do not execute workloads, populate caches, invoke external tools, or + write reports. +- **Evidence execution**: run the bounded commands and tools authorized by the + user. State expected cost, restricted dependencies, and output locations + before expensive or commercial-tool work. +- **Implementation acceptance**: inspect the change and run risk-proportionate + evidence, but do not repair findings unless the user also requested fixes. + +A request for review, audit, status, or diagnosis defaults to inspection-only +unless it explicitly requests execution. Never transition from a finding to a +source or documentation edit without separate authorization. + +## Define The Claim + +1. State the capability or completion claim narrowly enough to falsify. +2. Resolve the current Git revision, semantic configuration, input artifact + identities, tool identities, and requested fidelity. +3. Locate the normative conformance boundary through `docs/README.md`. +4. List the producers, independent verifiers or oracles, and terminal outcomes + required by that boundary. +5. Read [the domain evidence checks](references/evidence-checks.md) for the + affected workflow. + +Do not mutate source during a requested audit or diagnosis. If the user asks +for implementation, finish the audit classification before editing. + +## Build The Evidence Matrix + +Use one row per independently falsifiable claim: + +| Claim | Required evidence | Observed evidence | Identity | Terminal outcome | Verdict | Limits | +|---|---|---|---|---|---|---| + +Use only these claim verdicts: + +- **Proven**: evidence directly establishes the exact claim. +- **Contradicted**: a valid counterexample refutes the claim. +- **Unresolved**: available evidence establishes neither result. + +Record the exact typed terminal outcome owned by the current workflow. Examples +include success, adverse completed evidence, unsupported semantics, invalid +input, proven infeasibility, budget exhaustion, execution failure, +unavailability, interruption, and not attempted. These examples are not a new +product enum; use the canonical owner's current terms. Do not collapse terminal +outcomes into a claim verdict. + +## Inspect Or Collect Evidence + +In inspection-only mode, evaluate only evidence that already exists. Record +unattempted execution as a limit and stop when new execution would be required +to resolve the claim. + +In evidence-execution or implementation-acceptance mode: + +1. Validate artifact closure, exact references, resolved configuration, and + tool readiness before expensive execution. +2. Run the smallest realistic production path that can prove or refute the + claim. Inspect its artifacts and trace rather than only its exit status. +3. Compare against an independent reference or exact verifier. A producer + cannot be its own oracle. +4. Use a negative control or near-neighbor to prove that the gate distinguishes + real behavior from unconditional success. +5. Expand from a representative case to a bounded cohort only after the stage + and failure taxonomy are established. +6. Record exact commands, semantic environment, identities, time and resource + budgets, terminal state, and raw evidence under an ignored experiment + directory. +7. Re-run risk-proportionate evidence at the final combined revision. +8. Preserve evidence required for review or reproduction through its canonical + artifact owner or an approved durable report or evidence store. A `temp/` + path alone is never acceptance evidence. + +For implementation acceptance, inspect the affected dependency cone and run +focused anchors before broader suites. Run commercial or expensive EDA only +when the claim requires that fidelity, the affected owner changed, or the user +explicitly requests it. + +## Guard Evidence Integrity + +- Do not count empty graphs, skipped stages, dummy traces, X-filled shells, + universal resources, stale artifacts, feature-gated tests, or mocks as the + real capability. +- Do not widen a narrow fixture or minimal workload into a corpus, application, + or full-stack completion claim. +- Do not treat a timeout as infeasibility or an interrupted test as a pass. +- Do not raise timeouts before checking capacity, identity, stage accounting, + isolated execution, resource contention, and algorithmic progress. +- Require exact integer, address, control, ordering, and non-floating memory + behavior. Allow floating differences only when their semantic provenance is + established by the owning contract. +- Verify cold and warm cache behavior separately when cache correctness or + performance is claimed. A warm result must prove the expensive tool was not + invoked. +- Rebuild stale readiness or derived outputs through their owner rather than + editing reports. + +## Report The Result + +Lead with contradictions and missing evidence. Include the evidence matrix, +commands or machine-readable reports, artifact roots, identities, resource +limits, and residual unsupported boundaries. + +Recommend `$loom-spec-driven-change` when evidence demonstrates that the +current normative contract is defective. Invoke it in design mode unless the +user separately authorized documentation or implementation changes. Use +`$loom-context-recovery` before trusting claims recovered from a long or +interrupted session. diff --git a/.agents/skills/loom-evidence-audit/agents/openai.yaml b/.agents/skills/loom-evidence-audit/agents/openai.yaml new file mode 100644 index 000000000..4f2f8e07a --- /dev/null +++ b/.agents/skills/loom-evidence-audit/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Loom Evidence Audit" + short_description: "Validate Loom capability claims with exact evidence" + default_prompt: "Use $loom-evidence-audit to verify this Loom capability claim with exact artifacts and realistic evidence." diff --git a/.agents/skills/loom-evidence-audit/references/evidence-checks.md b/.agents/skills/loom-evidence-audit/references/evidence-checks.md new file mode 100644 index 000000000..c7f520ff2 --- /dev/null +++ b/.agents/skills/loom-evidence-audit/references/evidence-checks.md @@ -0,0 +1,84 @@ +# Domain Evidence Checks + +Load only the sections relevant to the claim. Resolve exact semantics and +current command names from tracked specifications, source, and `--help`. + +## Artifacts And Identity + +- Trace authoring input, canonical payload, identity, strict import, + publication, and consumer reference. +- Re-import the emitted payload through the canonical importer. +- Check semantic-equivalence stability and semantic-change sensitivity. +- Reject foreign, stale, wrong-kind, and incomplete references. +- Confirm reports and caches remain derived rather than alternate authorities. + +## Source And Corpus + +- Define inventory units explicitly: source member, translation unit, program, + source variant, workload, and emitted graph are not interchangeable. +- Derive the inventory from its current canonical owner. Do not maintain a + private kernel list in the audit. +- Separate harness failures, source incompatibility, frontend rejection, + graph-free disposition, Mapping rejection, execution failure, and oracle + mismatch. +- Establish the taxonomy on a small representative set before a bounded cohort + scan. + +## Mapping And PnR + +- Bind the exact software and Fabric/System artifact roots and resolved policy. +- Determine whether failure occurs in candidate creation, finalization, + admission, placement, routing, closure, publication, or import. +- Distinguish proven infeasibility, known feasible but not found, resource + constraint, performance regression, and environment contention. +- Use exact cuts or capacity proofs for infeasibility and verifier-accepted + witnesses for feasibility. +- Run an isolated reproduction before attributing a timeout observed under + broad parallel load. +- Do not use raw actor/PE counts, a larger target, or a longer timeout as a + substitute for the owning legality proof. + +## Simulation And Runtime + +- Confirm the graph or mapped design actually executed. +- Bind runtime input, memory initialization, selected decisions, ABI, and + completion semantics exactly. +- Compare typed values, logical objects, byte effects, ordering, and control + against an independent reference. +- Locate the first semantic divergence before changing a comparator or error + tolerance. +- Preserve the same host envelope when replaying a selected implementation. + +## RTL And EDA + +- Inspect environment modules before declaring a tool unavailable. +- Use complete authored fixtures and ignored scratch roots. Do not track + commercial inputs, libraries, logs, or generated products. +- Record exact executable, version or readiness identity, libraries, corner, + target, and invocation. +- Strictly re-import generated outputs through the canonical backend owner. +- Label analytic estimates, smoke tests, RTL simulation, synthesis, place and + route, and measured hardware as distinct fidelity levels. +- Do not let a shell, lint pass, or analytic estimate stand in for functional + RTL or physical evidence. + +## Cache And External Tools + +- Include every semantic input and fault mode in the cache identity. +- Prove a cold execution invokes the expected tool and publishes a complete + result transactionally. +- Prove a warm execution returns the same semantic result without invoking the + expensive tool. +- Treat an unexpected warm miss or unexpected hit as a cache defect, not a + performance footnote. + +## Completion Claims + +- Decompose the requested outcome into independently falsifiable rows. +- Bind every row to an exact artifact, verifier, or real-tool result. +- Keep implementation presence, verification, unsupported capability, and + unattempted work separate. +- A coherent local slice does not imply that its enclosing research plan or + application is complete. +- Re-evaluate all rows after integration; evidence from an older isolated + revision does not prove the final composition. diff --git a/.agents/skills/loom-github-research-workflow/SKILL.md b/.agents/skills/loom-github-research-workflow/SKILL.md new file mode 100644 index 000000000..8cade6ff7 --- /dev/null +++ b/.agents/skills/loom-github-research-workflow/SKILL.md @@ -0,0 +1,105 @@ +--- +name: loom-github-research-workflow +description: Manage Loom research through private GitHub Projects and publish approved implementation work through public Issues and pull requests. Use to inspect or update a research Project README or fields, promote a private draft item, create or triage an Issue, link a branch or pull request, record evidence or gate decisions, or reconcile Project status after review or merge. Require an exact preview and explicit approval before every GitHub remote write. +--- + +# Loom GitHub Research Workflow + +Keep private research planning complete while exposing only approved, +actionable implementation work in the public repository. Discover live GitHub +objects and schemas on every use; never encode a Project number or field ID as +repository truth. + +Read [the privacy and promotion contract](references/privacy-and-promotion.md) +before drafting any public payload or changing a Project item. + +## Resolve Live State + +1. Confirm the authenticated GitHub identity and required scopes. +2. Resolve the repository, owner, default branch, Issue, pull request, and + linked Projects from the live API or an explicit URL. +3. Verify the selected Project is private, open, linked to the intended Loom + repository, and is the exact standalone research project requested. +4. Query the Project README, items, field definitions, option names, and + current workflows. Resolve IDs only for the pending operation. +5. Read the public Issue or pull request and current Git revision before + trusting a private draft's implementation status. + +Prefer `gh` and GitHub GraphQL for semantic operations. Use a signed-in browser +only when the required operation has no suitable API or CLI surface. + +## Separate The Authorities + +- Keep research thesis, hypotheses, alternatives, roadmap, dependencies, + unpublished evidence, gate decisions, and full progress in the private + Project. +- Keep the publishable implementation problem, governing Loom specs, bounded + work, acceptance evidence, and public discussion in the Issue. +- Keep HOW, review, and exact verification results in commits and the pull + request. +- Update product WHAT and WHY in `docs/` before implementation when the + research item changes Loom semantics. +- Keep each research Project self-contained. Do not point one Project at + another Project's roadmap or work item. +- Keep shared repository infrastructure outside all research Projects unless a + user explicitly assigns it to one. + +## Preview Every Remote Write + +Before any push, Issue, pull request, comment, label, assignment, close, merge, +Project, workflow, or field mutation, show: + +- authenticated identity and exact repository or Project URL; +- operation type and target IDs or URLs; +- complete public title and body; +- labels, assignees, milestone, base, head, and linkage changes; +- Project fields and before/after values; +- private source material deliberately omitted; +- the exact command or GraphQL mutation class to be used. + +Pause for explicit approval. Approval applies only to that payload and target. +If live state or the payload changes, preview again. After execution, read the +object back and report its URL and actual fields. + +## Promote A Private Draft + +1. Resolve the draft item and live `Public Promotion` field. Stop unless its + value is exactly `Approved`. +2. Draft a self-contained public Issue using only approved information and the + current Loom documentation owners. +3. Compare the exact draft title and body with the approved public payload. +4. If they are identical and safe to disclose, preview the in-place + `convertProjectV2DraftIssueItemToIssue` operation. This preserves the + Project item and its field values. +5. If private material must be omitted, preview a safe replacement transaction: + create the public Issue, add it to the same Project, copy approved field + values, verify the new item, then archive the original draft. Never delete + the original automatically. +6. Set or preserve a stable work-item key when the live Project provides one. + Do not copy private blocker graphs, comments, dates, or evidence links into + the public body. +7. Read back the Issue and Project item before reporting promotion success. + +If a required gate or field is absent or ambiguous, fail closed and request a +Project-owner decision rather than inventing a fallback. + +## Deliver Through Issue And Pull Request + +- Use the repository Issue forms when creating a public bug or change item. +- Link the Issue to the governing specification and rationale by stable path + and heading, not exact line ranges. +- Use `$loom-worktree-delivery` after the public work contract is accepted. +- Preview the remote branch push and complete Draft PR payload together. +- Link the pull request to the Issue it will actually complete. Do not use a + closing keyword for partial work. +- Keep the pull request body public, English-only, and free of private Project + content or automated-tool attribution. +- After review, merge, or new evidence, preview the exact Project status, + evidence, link, and gate-decision updates before applying them. +- Do not infer research completion from a merged implementation pull request. + +## Required Output + +Report the private Project URL to authorized collaborators, public Issue and +pull request URLs, governing docs revision, Project item key, executed field +changes, omitted private categories, and any remaining review or evidence gate. diff --git a/.agents/skills/loom-github-research-workflow/agents/openai.yaml b/.agents/skills/loom-github-research-workflow/agents/openai.yaml new file mode 100644 index 000000000..d999a8c67 --- /dev/null +++ b/.agents/skills/loom-github-research-workflow/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Loom GitHub Research Workflow" + short_description: "Bridge private research planning to public delivery" + default_prompt: "Use $loom-github-research-workflow to move this Loom research item through private planning and public delivery." diff --git a/.agents/skills/loom-github-research-workflow/references/privacy-and-promotion.md b/.agents/skills/loom-github-research-workflow/references/privacy-and-promotion.md new file mode 100644 index 000000000..4080d21b1 --- /dev/null +++ b/.agents/skills/loom-github-research-workflow/references/privacy-and-promotion.md @@ -0,0 +1,85 @@ +# Privacy And Promotion Contract + +Apply this contract to every Loom research Project. Project visibility and +field definitions are live GitHub state and must be queried, not assumed. + +## Private Planning Content + +Keep these categories private unless the owner explicitly approves their exact +public wording: + +- complete research roadmaps and Project README content; +- unpublished hypotheses, alternatives, negative results, and novelty claims; +- cross-item blocker graphs and internal scheduling; +- private comments, collaborators, dates, effort estimates, and priorities; +- evidence roots, dashboards, or attachments with non-public paths or data; +- gate discussions and decisions not yet selected for publication; +- information copied from another standalone research Project. + +The existence of a public Issue does not authorize copying its surrounding +private plan. + +## Public Issue Content + +A promoted Issue should contain only: + +- a concise public problem statement; +- the affected Loom component and current observable gap; +- stable links to owning specifications and rationales; +- the bounded implementation contract and explicit non-goals; +- acceptance evidence that can be collected publicly; +- public reproduction details and sanitized artifact identities; +- known public limitations needed for honest review. + +Write the Issue so a contributor can act without access to the private +Project. Do not expose enough neighboring work to reconstruct the hidden +roadmap. + +## Approval Snapshot + +The preview must show the full rendered public payload and every mutation in +one approval snapshot. Approval is invalid when any of these change: + +- authenticated account; +- repository, Project, item, base branch, or head branch; +- title, body, comment, labels, assignees, or milestone; +- Project field names, option values, or work-item key; +- conversion, replacement, archive, close, merge, or push behavior. + +Read back the live object after mutation. A successful CLI exit alone is not +enough. + +## Promotion Paths + +### In-Place Conversion + +Use only when the private draft title and body are already the exact approved +public payload. Query the live repository ID and item ID, preview the conversion +mutation, obtain approval, convert, then verify the Issue URL and preserved +Project fields. + +### Redacted Replacement + +Use when the draft contains private detail: + +1. Preview the sanitized Issue and complete field-copy/archive transaction. +2. Create the Issue after approval. +3. Add it to the same private Project. +4. Copy only approved field values from the draft. +5. Verify the Issue item, stable work-item key, and linkage. +6. Archive the old draft so it remains recoverable but is no longer active. + +If any operation fails, report the partial state exactly. Do not delete or hide +the evidence and do not retry with a broader mutation. + +## Pull Requests And Evidence + +- The Issue is the public work contract; the pull request implements it. +- A Draft PR may link the Issue, but a closing keyword is appropriate only when + merging the complete PR should close that Issue. +- Keep exact test commands, public artifact references, and limitations in the + pull request. +- Keep unpublished research interpretation and aggregate roadmap status in the + private Project. +- Project automation may derive status from Issue or PR events, but verify the + resulting live fields before relying on them. diff --git a/.agents/skills/loom-spec-driven-change/SKILL.md b/.agents/skills/loom-spec-driven-change/SKILL.md new file mode 100644 index 000000000..3bc7ec732 --- /dev/null +++ b/.agents/skills/loom-spec-driven-change/SKILL.md @@ -0,0 +1,108 @@ +--- +name: loom-spec-driven-change +description: Define and deliver Loom changes from canonical WHAT and WHY before implementing HOW. Use for architecture, IR, schema, artifact, identity, Mapping, simulation, runtime, hardware, Evaluation, or other cross-component semantic changes; for suspected spec/code conflicts; or when a review exposes an undefined or duplicated semantic owner. Do not use for a behavior-preserving local edit whose existing contract is already clear. +--- + +# Loom Spec-Driven Change + +Use tracked documentation to close the semantic contract before changing its +implementation. Treat the current specification as implementation authority, +but let reproducible evidence challenge and improve it at its owner. + +## Confirm The Authorized Mode + +Choose the mode from the user's request before changing state: + +- **Design or review**: inspect, classify, and report. Do not edit or commit. +- **Documentation change**: update and commit WHAT/WHY only. Stop before HOW. +- **Full change**: update and commit WHAT/WHY when needed, then implement HOW in + later commits. + +A review that discovers a defect does not authorize a fix. A request to +implement a semantic change authorizes the full workflow unless the user +narrows it. + +## Establish The Authority + +1. Read the repository `AGENTS.md` and `docs/README.md`. +2. Follow `docs/spec-loom-stack.md` and `docs/rationales/README.md` to the + narrowest normative owner and its rationale. +3. Inspect the live implementation, conformance anchors, and affected + producers and consumers. Treat plans, transcripts, Issues, and `temp/` as + context rather than product authority. +4. Read [the authority checklist](references/authority-checklist.md) when the + change crosses an artifact, identity, schema, or component boundary. + +## Classify The Change + +First require an observable distinction, intended semantic owner, and affected +consumer. If the proposal does not define them, report it as underspecified and +stop before a broad implementation audit. + +Choose exactly one primary classification for the proposed change: + +- **Implementation lag**: the current specification is closed and correct, + but HOW does not conform. +- **Specification gap**: an essential behavior has no complete normative + owner. +- **Specification defect**: a reproducible counterexample or architectural + contradiction invalidates the current contract. +- **Non-semantic implementation change**: behavior and public contracts remain + unchanged. Route a clearly local implementation task to the normal + repository workflow rather than continuing this skill. +- **No semantic change justified**: the current contract already represents + the requested distinction, or the proposal would add a duplicate owner. + Reject the proposed change and preserve the existing contract. + +Do not edit documentation merely to narrate implementation. Do not call an +unimplemented but coherent contract a defect. +Classify additional inconsistencies discovered during inspection separately; +they do not change the primary classification or authorize a repair. + +## Close WHAT And WHY + +For a gap or defect in documentation-change or full-change mode: + +1. State the problem with one concrete positive example and one counterexample. +2. Trace ownership, typed inputs and outputs, identity, ordering, validation, + failure behavior, version boundaries, and downstream consumers only where + the change affects them. +3. Compare the smallest viable designs. Prefer an existing owner or a derived + view over a new entity. +4. Update one current contract in the owning `spec-*.md` and explain the reason + in the corresponding rationale. Remove superseded alternatives from the + normative surface. +5. Verify links, terminology, internal consistency, and implementability. +6. Commit WHAT and WHY without product HOW changes. + +In design or review mode, report the same analysis without editing. If a +high-impact choice remains genuinely unresolved, present the evidence and +alternatives and stop before implementation. + +## Make HOW Conform + +After the documentation commit exists, or when the existing contract was +already sufficient: + +1. Record the exact documentation revision and public Issue that govern the + work. +2. Implement the complete affected owner slice in a later commit. +3. Migrate all consumers and delete any superseded parser, codec, cache, + fallback, alias, fixture, or test that no longer has an owner. +4. Exercise the production path with realistic input. +5. Retain only tests that protect fragile semantic joints. +6. Use `$loom-evidence-audit` before making a capability or completion claim. + +## Required Output + +Report the applicable subset of: + +- the normative and rationale owners; +- the change classification; +- the positive example and counterexample for a gap or defect; +- the selected contract and rejected shadow authorities; +- the WHAT/WHY commit and later HOW commits when changes were authorized; +- exact evidence and remaining unsupported boundaries. + +Never report the change as complete while WHAT, WHY, HOW, or required evidence +still disagree. diff --git a/.agents/skills/loom-spec-driven-change/agents/openai.yaml b/.agents/skills/loom-spec-driven-change/agents/openai.yaml new file mode 100644 index 000000000..581d3a919 --- /dev/null +++ b/.agents/skills/loom-spec-driven-change/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Loom Spec-Driven Change" + short_description: "Define WHAT and WHY before implementing Loom changes" + default_prompt: "Use $loom-spec-driven-change to define this Loom change from its canonical specifications before implementation." diff --git a/.agents/skills/loom-spec-driven-change/references/authority-checklist.md b/.agents/skills/loom-spec-driven-change/references/authority-checklist.md new file mode 100644 index 000000000..28371009c --- /dev/null +++ b/.agents/skills/loom-spec-driven-change/references/authority-checklist.md @@ -0,0 +1,72 @@ +# Authority Checklist + +Read this checklist for changes that cross semantic owners or durable artifact +boundaries. Resolve exact product facts from the current tracked +specifications; do not copy them into this reference. + +## Locate The Owner + +- Start with `docs/README.md` and the `Authority Map` in + `docs/rationales/README.md`. +- Identify the fact being changed, not merely the file or API being edited. +- Find its authoring owner, immutable artifact owner, derived views, and every + consumer that can observe the change. +- Determine whether an existing owner can derive the requested fact. +- Reject generic bags, name-keyed tables, caller-maintained lists, and cached + reports that would become competing authorities. + +## Test The Contract + +- Give one ordinary case that must work. +- Give one near-neighbor that must be rejected or behave differently. +- State which owner distinguishes the two cases. +- Check ordering, completion, memory effects, liveness, identity, and failure + behavior only where observable or contractually required. +- Distinguish semantic determinism from host timing, paths, licenses, and cache + state. + +## Durable Artifact Changes + +When an artifact or protocol changes, inspect the complete path: + +```text +authoring form + -> canonical payload + -> semantic identity + -> strict import and validation + -> publication + -> exact consumer reference +``` + +- Ensure presentation metadata, source order, host paths, and private names do + not alter identity unless the specification says they are semantic. +- Update schema or protocol identity when the same serialized value would + otherwise acquire new meaning. +- Reject foreign, wrong-kind, stale, and out-of-range references through the + owning typed failure model. +- Keep caches and reports derived. They must not define a second wire format or + terminal state. + +## Commit Boundary + +The documentation commit may contain specifications, rationales, and +documentation-only conformance definitions. It must not contain product source +or test changes that implement the new behavior. + +Later implementation commits must cite the governing documentation revision. +If implementation evidence reveals another contract defect, stop, amend the +owner in a new documentation commit, and then resume HOW. + +## Simplification Review + +After consumers migrate, inspect the dependency cone for: + +- old codecs, parsers, aliases, flags, and fallback paths; +- duplicated validation or status fields; +- test-only production hooks and fixtures; +- reports or caches treated as final authorities; +- defensive states made impossible by the new invariant. + +Remove obsolete machinery only after checking direct and dynamic consumers, +registries, build and link ownership, command entry points, serialized +contracts, and external integrations. diff --git a/.agents/skills/loom-worktree-delivery/SKILL.md b/.agents/skills/loom-worktree-delivery/SKILL.md new file mode 100644 index 000000000..eac6598c2 --- /dev/null +++ b/.agents/skills/loom-worktree-delivery/SKILL.md @@ -0,0 +1,107 @@ +--- +name: loom-worktree-delivery +description: Create, use, synchronize, review, integrate, publish, or safely clean an isolated Loom linked worktree for a bounded implementation task. Use after WHAT and WHY are closed, when starting work from an Issue, coordinating non-overlapping parallel owners, recovering worktree state, or preparing a branch and pull request. Do not use to invent unresolved architecture or to manipulate another active worker's state. +--- + +# Loom Worktree Delivery + +Deliver one coherent semantic owner slice through one branch and one linked +worktree. Keep topology and state explicit; use existing repository entry +points for build and synchronization behavior. + +Read [the delivery checklist](references/delivery-checklist.md) before creating, +integrating, or cleaning a worktree. + +## Confirm The Authorized Mode + +- **Preparation**: inspect and propose topology, ownership, evidence, and stop + conditions. Do not create or mutate worktrees, refs, or remote state. +- **Local delivery**: an explicitly approved task permits local worktree, + branch, implementation, verification, and commits. It does not permit a + remote write. A public Issue may remain pending while its exact payload is + awaiting approval. +- **Publication**: require the accepted public Issue and the exact remote-write + approval required by `$loom-github-research-workflow` before push or pull + request creation. + +## Establish The Delivery Contract + +Require: + +- a public Issue for publication, or an explicitly approved task for local + delivery; +- the exact governing specification and, when applicable, rationale revision; +- a bounded semantic owner and affected dependency cone; +- non-overlapping worktree ownership; +- acceptance evidence and known expensive tools; +- the base reference, integration owner, and publication target. + +If product semantics are unresolved, use `$loom-spec-driven-change` and stop +implementation. Do not ask a builder to choose architecture implicitly. + +## Create Or Adopt A Worktree + +1. Inspect live worktree topology and resolve the repository common directory, + base reference, branch, and explicit target path. +2. Require the exact target path from the user's request or accepted task. If + it is absent, stop before topology mutation rather than assuming a + maintainer-specific home directory or organization-internal layout. +3. Validate that the target path is absent and narrow, the base is current, and + the branch is not owned by another worktree. +4. Create one branch for one task. Do not share a writable worktree among + agents. +5. Run `make doctor` in the linked worktree before relying on build paths or + shared externals. + +Use normal `git worktree` operations for topology. Use the repository Makefile +and scripts for Loom-specific build identity, shared external tools, and linked +branch synchronization. Do not reimplement those mechanisms in this skill. +Process listings are evidence of activity, not ownership authority. Require an +explicit owner acknowledgment when live topology or activity is ambiguous. + +## Implement And Verify + +1. Re-read the Issue and governing documentation from the adopted revision. +2. Inspect the current implementation before assuming a historical gap still + exists. +3. Implement the complete owner slice and remove superseded paths in the same + dependency cone. +4. Exercise the realistic use path, then retain only qualifying tests. +5. Run `$loom-evidence-audit` at the scope needed by the claim. +6. Review the final diff for unrelated changes, hidden compatibility, private + paths, generated artifacts, and documentation drift. +7. Commit coherent changes in English. Product WHAT/WHY commits must precede + product HOW commits. + +## Synchronize And Integrate + +- Recheck cleanliness, ancestry, active owners, and the actual commit delta + immediately before integration. +- In local-delivery mode, use `make sync-worktree` only from a linked worktree + and only when synchronization is within the approved task. Inspect its + documented preflight result before accepting any update. Do not run it in + preparation mode. +- Resolve conflicts by semantic owner. Never use whole-file conflict choices + where both sides contain independent valid behavior. +- Rebuild and re-run risk-proportionate evidence on the combined revision. +- Prove the delivered commits are reachable from the intended target before + considering cleanup. + +## Publish And Clean + +Before push, Issue edits, pull request creation, merge, or Project updates, use +`$loom-github-research-workflow` and obtain approval for the exact remote +payload. + +Cleanup is a separate destructive action. Remove a linked worktree or branch +only when the user requests it and live checks prove that it is inactive, +clean, fully integrated, and not the sole owner of any commit or artifact. +Prefer a recoverable operation when practical. + +## Required Output + +Report the applicable Issue or local authorization, docs revision, worktree +path, branch, semantic owner, commit delta, verification evidence, integration +target, publication URLs, and any state intentionally left for another owner. +Mark artifacts that were not created or published as such instead of inventing +placeholder state. diff --git a/.agents/skills/loom-worktree-delivery/agents/openai.yaml b/.agents/skills/loom-worktree-delivery/agents/openai.yaml new file mode 100644 index 000000000..b57e39929 --- /dev/null +++ b/.agents/skills/loom-worktree-delivery/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Loom Worktree Delivery" + short_description: "Deliver an isolated Loom change through a worktree" + default_prompt: "Use $loom-worktree-delivery to implement and deliver this bounded Loom change in an isolated worktree." diff --git a/.agents/skills/loom-worktree-delivery/references/delivery-checklist.md b/.agents/skills/loom-worktree-delivery/references/delivery-checklist.md new file mode 100644 index 000000000..53e7c6d39 --- /dev/null +++ b/.agents/skills/loom-worktree-delivery/references/delivery-checklist.md @@ -0,0 +1,58 @@ +# Delivery Checklist + +Use this checklist at topology-changing and publication boundaries. Do not run +Git inspection repeatedly when state has not changed. + +## Preflight + +- Resolve the repository root and common Git directory. +- Inspect `git worktree list --porcelain` for branch and path ownership. +- Verify the exact base reference and intended branch ancestry. +- Check the target worktree and integration worktree for local changes. +- Check for an active process or agent that owns either worktree. +- Treat process discovery as evidence only; obtain explicit acknowledgment + when ownership is not already established by the task. +- Validate the explicit target path; do not use broad directories, home + shortcuts, unresolved variables, or globs for destructive commands. +- Run `make doctor` after the linked worktree exists. + +## Ownership Contract + +- One writable worktree has one active owner. +- Parallel slices must have non-overlapping semantic owners or an explicit + integration dependency. +- Leaf worktrees deliver to their declared integration owner rather than + bypassing it. +- Submodules and shared external build roots remain under their repository + owner. +- Stashes are short-lived recovery tools, not cross-worktree storage or + handoff records. + +## Implementation Review + +- Confirm the historical gap still exists on the current base. +- Confirm source changes implement the governing specification revision. +- Inspect direct and dynamic consumers before deleting old behavior. +- Check build registration, link ownership, command entry points, schemas, + external tools, and generated artifacts. +- Keep site-local paths, commercial data, logs, and ignored outputs untracked. +- Run focused evidence before broad or expensive gates. + +## Integration Review + +- Recompute ancestry and commit deltas after the final local commit. +- Identify semantic overlaps before applying commits. +- Preserve the newer shared contract and both branches' independent valid + capabilities. +- Run evidence at the combined revision, not only at an isolated source tip. +- Verify the remote result after an approved push. + +## Cleanup Review + +- Require explicit cleanup authorization. +- Confirm no active owner or process remains. +- Confirm the worktree is clean and its commits are reachable from the retained + target. +- Confirm no untracked artifact is the only copy of required evidence. +- Remove only the explicit linked worktree and branch; never use a repository + root or broad parent directory as a recursive target. diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 000000000..8cfa7bceb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,95 @@ +name: Bug report +description: Report reproducible incorrect Loom behavior +title: "[Bug]: " +labels: + - bug +body: + - type: markdown + attributes: + value: | + Describe only information approved for the public Loom repository. Do not copy private Project roadmaps, comments, dates, blocker graphs, or unpublished evidence. + + - type: textarea + id: summary + attributes: + label: Public summary + description: State the incorrect behavior and why it matters. + placeholder: Loom produces or accepts an incorrect result when... + validations: + required: true + + - type: input + id: component + attributes: + label: Affected component or workflow + description: Name the narrowest compiler, hardware, Mapping, simulation, runtime, Evaluation, build, or agent-infrastructure area. + placeholder: Spatial Mapping artifact import + validations: + required: true + + - type: input + id: specification + attributes: + label: Normative WHAT owner + description: Link the current spec path and stable heading. State "Unknown" only when locating the owner is part of the bug. + placeholder: docs/spec-...md, heading ... + validations: + required: true + + - type: input + id: rationale + attributes: + label: Rationale WHY owner + description: Link the corresponding rationale path and stable heading, when one exists. + placeholder: docs/rationales/...md, heading ... + validations: + required: false + + - type: textarea + id: observed + attributes: + label: Observed behavior + description: Include the typed failure or exact terminal state. Do not report a timeout as infeasibility. + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: State the behavior required by the current specification or explain the suspected specification defect. + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Reproduction + description: Provide the smallest realistic input and production command that reproduces the bug. + render: shell + validations: + required: true + + - type: textarea + id: evidence + attributes: + label: Evidence and artifact identity + description: Give public logs, exact artifact roots or digests, independent oracle results, and negative controls where available. + validations: + required: true + + - type: textarea + id: environment + attributes: + label: Environment and tool identity + description: Include the Loom revision, semantic configuration, and relevant compiler, simulator, EDA, or operating-system identity. + validations: + required: true + + - type: checkboxes + id: privacy + attributes: + label: Public disclosure check + options: + - label: I removed private Project planning, unpublished research material, credentials, private paths, and restricted artifacts from this report. + required: true diff --git a/.github/ISSUE_TEMPLATE/change.yml b/.github/ISSUE_TEMPLATE/change.yml new file mode 100644 index 000000000..9c4b2080c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/change.yml @@ -0,0 +1,88 @@ +name: Implementation change +description: Propose a bounded, publishable Loom implementation change +title: "[Change]: " +labels: + - enhancement +body: + - type: markdown + attributes: + value: | + This Issue is a public implementation contract, not a research roadmap. Keep complete hypotheses, planning, dependencies, and gate discussions in the private Project. + + - type: textarea + id: goal + attributes: + label: Public goal + description: State the user-visible or research-enabling outcome without disclosing the surrounding private roadmap. + validations: + required: true + + - type: textarea + id: current-gap + attributes: + label: Current gap + description: Describe the current behavior and the exact missing or incorrect capability. + validations: + required: true + + - type: dropdown + id: authority-classification + attributes: + label: Authority classification + description: Select how this change relates to the current Loom product contract. + options: + - Implementation must catch up to the existing specification + - Specification and rationale must change before implementation + - No Loom product semantics change + validations: + required: true + + - type: input + id: specification + attributes: + label: Normative WHAT owner + description: Link the current spec path and stable heading, or state that the change is repository infrastructure only. + placeholder: docs/spec-...md, heading ... + validations: + required: true + + - type: input + id: rationale + attributes: + label: Rationale WHY owner + description: Link the corresponding rationale path and stable heading, when applicable. + placeholder: docs/rationales/...md, heading ... + validations: + required: false + + - type: textarea + id: implementation-boundary + attributes: + label: Implementation boundary + description: Define the coherent owner slice, affected consumers, and public deliverables. + validations: + required: true + + - type: textarea + id: non-goals + attributes: + label: Non-goals + description: Identify adjacent behavior this Issue deliberately does not claim or change. + validations: + required: true + + - type: textarea + id: acceptance-evidence + attributes: + label: Acceptance evidence + description: List realistic production paths, independent verifiers, artifacts, and required fidelity. + validations: + required: true + + - type: checkboxes + id: privacy + attributes: + label: Public disclosure check + options: + - label: I removed private Project planning, unpublished research material, credentials, private paths, and restricted artifacts from this proposal. + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..3ba13e0ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..fd41debdc --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,37 @@ +## Summary + +Describe the bounded public outcome and the reason for the change. + +## Issue + +Link the public Issue. Use a closing keyword only when merging this pull request should complete the entire Issue. + +## Specification And Rationale + +- Normative WHAT owner: +- Rationale WHY owner: +- Preceding documentation commit: +- Product semantics unchanged: + +For a semantic change, the documentation commit must precede implementation commits. For a behavior-preserving change, identify the existing contract instead of adding decorative documentation. + +## Implementation + +Describe the coherent owner slice, affected consumers, removed obsolete paths, and explicit non-goals. + +## Evidence + +List exact commands, realistic inputs, artifact or tool identities, independent verifiers, and terminal results. Distinguish unsupported, unavailable, incomplete, and adverse evidence from success. + +## Known Limits + +State remaining unsupported behavior and the boundaries this pull request does not claim to close. + +## Review Checklist + +- [ ] The change follows the current normative specification. +- [ ] No private Project roadmap, comment, date, blocker graph, or unpublished evidence is disclosed. +- [ ] No credential, restricted artifact, site-local path, or generated commercial-tool output is tracked. +- [ ] Tests retained by this change protect necessary and non-trivial semantic joints. +- [ ] The final combined revision was exercised at the fidelity required by the claim. +- [ ] Commit messages and this pull request are English-only and contain no automated-tool attribution. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..a346eea8a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,172 @@ +# Loom Agent Development + +This file defines repository development policy for coding agents. It does not +define Loom product semantics. Product contracts remain in `docs/`. + +## Authority + +- Start at [`docs/README.md`](docs/README.md). Tracked `docs/spec-*.md` files + own normative WHAT. [`docs/spec-loom-stack.md`](docs/spec-loom-stack.md) is + the full-stack entry point. +- [`docs/rationales/README.md`](docs/rationales/README.md) maps specifications + to non-normative WHY documents. A rationale explains a choice but never owns + schemas, behavior, defaults, or validation rules. +- Source code owns HOW and must conform to the current specifications. +- A coherent specification may intentionally lead its implementation. Do not + delete or weaken it merely because HOW is incomplete. +- Real evidence may reveal a defective specification. In that case, repair the + owning specification and rationale first; never create a code-only alternate + contract. +- Private GitHub Projects own research roadmaps, hypotheses, and progress. + Public Issues own publishable implementation work, and pull requests own the + corresponding review and delivery record. None of these override product + semantics in `docs/`. +- `temp/` is ignored scratch space. Nothing required to understand, implement, + review, or reproduce Loom may depend on it. + +## Architecture Orientation + +Loom is a full-stack compiler and hardware framework for heterogeneous, +multicore spatial acceleration. Its stable conceptual flow is: + +```text +source programs + -> structured and Dataflow artifacts + -> Fabric and ADG hardware artifacts + -> Tech, Spatial, and System Mapping + -> simulation, runtime, RTL, and physical-tool evidence + -> Evaluation and design-space exploration +``` + +The compiler frontend, hardware frontend, Mapping, simulation backends, +hardware backend, and Evaluation/DSE are the six semantic components described +under `Full-Stack Components` in `docs/spec-loom-stack.md`. Follow links from +the documentation entry points to learn exact interfaces. Do not copy current +schemas, algorithms, presets, version numbers, or capability counts into this +file or an agent skill. + +## Spec-Driven Changes + +Architecture, IR, schema, artifact, cross-component, and externally visible +semantic changes require one closed normative owner and its rationale. When a +decision changes, commit the selected WHAT and WHY without product HOW, then +implement HOW in later commits. If existing WHAT and WHY are already +sufficient, reference them and avoid decorative documentation churn. Stop +implementation while an essential semantic owner remains unresolved. + +Repository procedures for this work live under `.agents/skills/`. Use the +matching skill instead of recreating a parallel checklist in a plan or Issue. + +## Engineering Rules + +### Distilled Foundations + +- Introduce a concept only when it represents an essential distinction that + cannot be derived from an existing owner. +- Give every fact, rule, schema, configuration value, identity, and state + transition one semantic owner. Derived views and caches must identify their + source and validation rule. +- Prefer composition and stronger invariants over special cases, fallback + ladders, compatibility aliases, generic property bags, and caller-maintained + shadow state. +- Simplify the affected dependency cone after behavior is proven. Remove + obsolete paths completely, but first check dynamic consumers, registries, + build and link ownership, serialized contracts, entry points, and external + integrations. +- Do not classify a missing required capability, typed failure distinction, + independent oracle, or durable diagnostic as slop. + +### Types And Diagnostics + +- Represent closed internal domains with typed enums or tagged types. In C++, + use `enum class`. Convert strings only at parsing, serialization, logging, + and display boundaries through one canonical mapping. +- Give repeated domain-significant values semantic names under their owner. +- Keep reusable diagnostics quiet by default and runtime-configurable. Remove + case-specific probes after the investigation. +- Treat schema, protocol, cache-key, and artifact-identity changes as one + semantic change. Never reuse an old identity for new meaning. + +### Tests And Evidence + +- Tests are evidence, not the default development process. Understand the + contract and implement a coherent workflow before deciding which tests are + worth retaining. +- Follow any conformance-anchor ordering required by the owning specification. + This does not imply universal per-function or fixture-first development. +- Commit a test only when it is necessary, reusable, likely to catch a + plausible regression, and non-trivial. +- Prefer realistic inputs, production entry points, exact artifacts, strict + import, typed failures, and independent oracles over mocks and wrappers. +- A green narrow test, an empty artifact, a generated shell, a dummy trace, a + feature-gated test, or `Unsupported` cannot prove a broader capability. +- Distinguish `Unsupported`, invalid input, proven infeasibility, budget + exhaustion, execution failure, adverse evidence, and success. +- Give expensive searches and tools explicit CPU, memory, concurrency, and + timeout budgets. Diagnose timeouts before increasing them. + +### Files And Modules + +- Keep tracked files English-only and free of Emoji. Scratch files under + `temp/` are exempt. +- Use semantic anchors such as symbol and heading names in documentation and + plans. Do not cite fragile exact line ranges. +- Avoid large production-code blocks in specifications and plans. Use + pseudocode and concise interface signatures. +- Review a code file's responsibility at 2,000 lines. Files between 2,000 and + 4,000 lines require a behavior-preserving modularization review after the + coherent implementation works. No code file may exceed 4,000 lines. +- Split modules by cohesive responsibility, not with arbitrary fragments, + `.inc` files, or pass-through wrappers used only to reduce line count. + +## Workspace And Tools + +- Use `rg` and `rg --files` for search. Prefer structured parsers for + structured data. +- Every command must reduce uncertainty, produce evidence, or perform an + authorized action. Do not run filler probes or repeatedly inspect unchanged + Git state. +- Use the current worktree for the assigned owner only. Do not modify, pause, + merge, or clean another active worker's worktree without authorization. +- Require an explicit linked-worktree target path from the current user's + request or accepted task. If it is absent, inspect live topology but do not + invent a default parent. Never encode a maintainer-specific home directory + or organization-internal layout in repository policy. Validate explicit + paths before any destructive or recursive operation. +- Prefer `temp/` for experiments and transient logs. Avoid `/tmp` for large + artifacts because the root filesystem may be small. +- When a development or EDA tool is absent, use an existing `module` command + to inspect `module avail`. If `module` is unavailable but + `/etc/profile.d/modules.sh` exists, source that script first. Load a selected + module explicitly before declaring the tool unavailable. This is interactive + operator discovery only; product tool resolution must follow + [`docs/spec-external-tool-invocation.md`](docs/spec-external-tool-invocation.md) + and must not parse presentation-oriented `module avail` output. +- Discover required libraries from repository documentation, build + configuration, the active environment, or user input. Never encode + organization-internal storage or site-local library paths in tracked policy. +- Use `make doctor` for repository build-path preflight. Use the Makefile entry + points rather than duplicating worktree build logic. +- For long-running tmux work, send text without Enter, inspect it with + `capture-pane`, wait one second, and send Enter separately. + +## Git And GitHub + +- Preserve unrelated user changes. Never use destructive Git operations to + recover a convenient local state. +- Keep commit messages and pull request bodies in English, without CJK or + Emoji. Do not add automated-tool attribution or names to commits, pull + requests, or code comments. +- Do not encode development bookkeeping such as numbered progress stages or + completion labels in code, comments, commit messages, or pull request text. +- Develop publishable work through a public Issue, an isolated branch and + worktree, and a pull request. Link a pull request to the Issue it actually + completes. +- Keep each research Project standalone. A work item may use shared Loom + components but must not depend on another research Project's roadmap. +- Keep research Projects private. Public Issues, pull requests, and code must + contain only material approved for disclosure. +- Before any GitHub remote write, show the exact target, public payload, and + field changes. Execute only after explicit approval, then read the live state + back. This includes Issue, pull request, comment, label, Project, merge, and + push operations.