Skip to content

[codex] Add archive policy and concurrency boundaries#9

Merged
dd3ok merged 3 commits into
mainfrom
codex/archive-policy-concurrency
May 16, 2026
Merged

[codex] Add archive policy and concurrency boundaries#9
dd3ok merged 3 commits into
mainfrom
codex/archive-policy-concurrency

Conversation

@dd3ok
Copy link
Copy Markdown
Owner

@dd3ok dd3ok commented May 15, 2026

Summary

  • add archive_policy / archive_after_days validation and document manual vs review-time suggested archive behavior
  • update starter/template WATCHLIST files to default to archive_policy: manual
  • add concurrent edit and duplicate ID collision boundaries: re-read before write, avoid existing IDs, stop/report duplicate collisions
  • add deterministic semantic cases and fixtures for archive suggestions, manual archive policy, list-only no-mutation reviews, and duplicate ID handling
  • bump release metadata to 0.3.0

Validation

  • python3 -m unittest discover -s evals -p 'test_*.py'
  • python3 evals/check_semantic_cases.py
  • python3 evals/check_watchlist.py .watchlist/WATCHLIST.md --strict-format --strict-safety --require-archive-section
  • python3 evals/check_watchlist.py .agents/skills/watchlist-md/assets/WATCHLIST.template.md --strict-format --strict-safety --require-archive-section
  • python3 evals/check_watchlist.py evals/fixtures/*.watchlist.md --strict-format --strict-safety --require-archive-section
  • python3 evals/check_release_metadata.py
  • python3 evals/check_policy_markers.py
  • python3 -m py_compile evals/check_watchlist.py evals/check_policy_markers.py evals/check_release_metadata.py evals/check_semantic_cases.py evals/test_check_watchlist.py
  • git diff --check

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces version 0.3.0 of the WATCHLIST skill, adding support for configurable archive policies (manual and suggest) and a new concurrent edit/ID collision policy. Key changes include updates to the documentation, schema, and validation logic to handle archive_policy and archive_after_days fields, along with new evaluation cases to ensure correct behavior during reviews and item additions. Feedback was provided regarding the validation of top-level fields, specifically recommending explicit detection of duplicate or unknown fields and ensuring that archive_after_days is present when the suggest policy is active.

Comment thread evals/check_watchlist.py Outdated
Comment on lines +220 to +288
def top_level_fields(text: str) -> dict[str, str]:
text = strip_html_comments(text)
preamble = re.split(r"^##\s+", text, maxsplit=1, flags=re.M)[0]
return {
match.group(1): match.group(2).strip()
for match in TOP_LEVEL_FIELD_RE.finditer(preamble)
}


def add_format_finding(
result: ValidationResult,
options: ValidationOptions,
code: str,
message: str,
) -> None:
if options.strict_format:
add_error(result, code, message)
else:
add_warning(result, code, message)


def validate_top_level_fields(text: str, result: ValidationResult, options: ValidationOptions) -> None:
fields = top_level_fields(text)
archive_policy = fields.get("archive_policy")
archive_after_days = fields.get("archive_after_days")

if archive_policy and archive_policy not in VALID_ARCHIVE_POLICIES:
add_error(
result,
"INVALID_ARCHIVE_POLICY",
f"Invalid archive_policy: {archive_policy}. Use manual or suggest.",
)

if archive_after_days is None:
return

try:
days = int(archive_after_days)
except ValueError:
add_error(
result,
"INVALID_ARCHIVE_AFTER_DAYS",
f"archive_after_days must be a positive integer: {archive_after_days}",
)
return

if days <= 0:
add_error(
result,
"INVALID_ARCHIVE_AFTER_DAYS",
f"archive_after_days must be a positive integer: {archive_after_days}",
)
return

if archive_policy is None:
add_format_finding(
result,
options,
"ARCHIVE_AFTER_DAYS_WITHOUT_POLICY",
"archive_after_days is only meaningful with archive_policy: suggest.",
)
elif archive_policy == "manual":
add_format_finding(
result,
options,
"ARCHIVE_AFTER_DAYS_WITH_MANUAL_POLICY",
"archive_after_days is only meaningful with archive_policy: suggest.",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of top-level field extraction and validation has several opportunities for improvement to ensure consistency with item-level field validation:

  1. Duplicate Detection: top_level_fields uses a dictionary comprehension that silently overwrites duplicate keys. It should explicitly detect and report duplicates, similar to fields_for_block.
  2. Unknown Field Detection: It should warn about unknown top-level fields (e.g., typos or unsupported keys) to maintain file integrity.
  3. Policy Logic: If archive_policy is set to suggest, archive_after_days should ideally be present to define the threshold. The current logic returns early if archive_after_days is missing, skipping this check.
  4. Robustness: The extraction and validation can be unified to avoid redundant preamble splitting and comment stripping.
def top_level_fields(text: str, result: ValidationResult, options: ValidationOptions) -> dict[str, str]:
    text = strip_html_comments(text)
    preamble = re.split(r"^##\s+", text, maxsplit=1, flags=re.M)[0]
    fields: dict[str, str] = {}
    known_fields = set(SKELETON_FIELDS) | {"archive_policy", "archive_after_days"}
    for match in TOP_LEVEL_FIELD_RE.finditer(preamble):
        key, value = match.group(1), match.group(2).strip()
        if key in fields:
            add_error(result, "DUPLICATE_TOP_LEVEL_FIELD", f"Duplicate top-level field: {key}")
        if key not in known_fields:
            add_format_finding(result, options, "UNKNOWN_TOP_LEVEL_FIELD", f"Unknown top-level field: {key}")
        fields[key] = value
    return fields


def add_format_finding(
    result: ValidationResult,
    options: ValidationOptions,
    code: str,
    message: str,
) -> None:
    if options.strict_format:
        add_error(result, code, message)
    else:
        add_warning(result, code, message)


def validate_top_level_fields(text: str, result: ValidationResult, options: ValidationOptions) -> None:
    fields = top_level_fields(text, result, options)
    archive_policy = fields.get("archive_policy")
    archive_after_days = fields.get("archive_after_days")

    if archive_policy and archive_policy not in VALID_ARCHIVE_POLICIES:
        add_error(
            result,
            "INVALID_ARCHIVE_POLICY",
            f"Invalid archive_policy: {archive_policy}. Use manual or suggest.",
        )

    if archive_policy == "suggest" and archive_after_days is None:
        add_format_finding(
            result,
            options,
            "MISSING_ARCHIVE_AFTER_DAYS",
            "archive_policy: suggest requires archive_after_days.",
        )

    if archive_after_days is not None:
        try:
            days = int(archive_after_days)
            if days <= 0:
                raise ValueError()
        except ValueError:
            add_error(
                result,
                "INVALID_ARCHIVE_AFTER_DAYS",
                f"archive_after_days must be a positive integer: {archive_after_days}",
            )
        else:
            if archive_policy != "suggest":
                code = "ARCHIVE_AFTER_DAYS_WITHOUT_POLICY" if archive_policy is None else "ARCHIVE_AFTER_DAYS_WITH_MANUAL_POLICY"
                add_format_finding(result, options, code, "archive_after_days is only meaningful with archive_policy: suggest.")

@dd3ok dd3ok marked this pull request as ready for review May 16, 2026 00:10
@dd3ok dd3ok merged commit 32f967a into main May 16, 2026
4 checks passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85be3ead48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

f"{', '.join(missing_forbidden)}"
)

if "on_duplicate_id" in expected:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require duplicate-ID contracts unconditionally for collision cases

For the new duplicate-ID semantic case, this gate only runs the collision checks when on_duplicate_id is present. If a future edit accidentally removes on_duplicate_id along with must_reread_before_write or must_avoid_existing_ids from duplicate-id-stop-and-report-kr, check_semantic_cases.py will treat it as an ordinary add-item case and still pass, so the eval no longer enforces the concurrency boundary this commit adds. Key the requirement off the collision case/fixture instead of the optional field itself.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant